2008-09-18 42 views
5

Tôi có ba mô hình:Làm thế nào để has_one: thông qua công việc?

class ReleaseItem < ActiveRecord::Base 
    has_many :pack_release_items 
    has_one :pack, :through => :pack_release_items 
end 

class Pack < ActiveRecord::Base 
    has_many :pack_release_items 
    has_many :release_items, :through=>:pack_release_items 
end 

class PackReleaseItem < ActiveRecord::Base 
    belongs_to :pack 
    belongs_to :release_item 
end 

Vấn đề là, trong thời gian thực hiện, nếu tôi thêm một gói vào một release_item nó không phải là nhận thức được rằng các gói là một gói. Ví dụ:

Loading development environment (Rails 2.1.0) 
>> item = ReleaseItem.new(:filename=>'MAESTRO.TXT') 
=> #<ReleaseItem id: nil, filename: "MAESTRO.TXT", created_by: nil, title: nil, sauce_author: nil, sauce_group: nil, sauce_comment: nil, filedate: nil, filesize: nil, created_at: nil, updated_at: nil, content: nil> 
>> pack = Pack.new(:filename=>'legion01.zip', :year=>1998) 
=> #<Pack id: nil, filename: "legion01.zip", created_by: nil, filesize: nil, items: nil, year: 1998, month: nil, filedate: nil, created_at: nil, updated_at: nil> 
>> item.pack = pack 
=> #<Pack id: nil, filename: "legion01.zip", created_by: nil, filesize: nil, items: nil, year: 1998, month: nil, filedate: nil, created_at: nil, updated_at: nil> 
>> item.pack.filename 
NoMethodError: undefined method `filename' for #<Class:0x2196318> 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1667:in `method_missing_without_paginate' 
    from /usr/local/lib/ruby/gems/1.8/gems/mislav-will_paginate-2.3.3/lib/will_paginate/finder.rb:164:in `method_missing' 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_collection.rb:285:in `send' 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_collection.rb:285:in `method_missing_without_paginate' 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/base.rb:1852:in `with_scope' 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_proxy.rb:168:in `send' 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_proxy.rb:168:in `with_scope' 
    from /usr/local/lib/ruby/gems/1.8/gems/activerecord-2.1.0/lib/active_record/associations/association_collection.rb:281:in `method_missing_without_paginate' 
    from /usr/local/lib/ruby/gems/1.8/gems/mislav-will_paginate-2.3.3/lib/will_paginate/finder.rb:164:in `method_missing' 
    from (irb):5 
>> 

Có vẻ như tôi nên có quyền truy cập vào item.pack, nhưng không biết rằng gói đó là một mục Pack.

Trả lời

6

Dường như việc bạn sử dụng has_one: thông qua là chính xác. Vấn đề bạn đang thấy phải làm với việc lưu các đối tượng. Để liên kết hoạt động, đối tượng đang được tham chiếu cần phải có id để điền vào trường model_id cho đối tượng. Trong trường hợp này, PackReleaseItems có một trường pack_id và trường release_item_id cần được điền để liên kết hoạt động chính xác. Thử lưu trước khi truy cập các đối tượng thông qua một liên kết.

+0

Nhưng nếu tôi sử dụng has_many: qua, thuộc_to hoặc has_one, tôi không phải lưu trước. – lordscarlet

+0

Vâng, dường như đã quan tâm đến nó. Tôi không nghĩ rằng tôi phải làm điều đó với các hiệp hội khác, mặc dù. – lordscarlet

+0

Điều đó có quan tâm đến nó không? Bạn có thể đăng clip của phiên giao diện điều khiển tương tác của mình không? Tôi đã thực hiện một ứng dụng thử nghiệm nhỏ bằng cách sử dụng Rails 2.1.0 và thậm chí lưu trước đó không giúp được tình huống, đó là lý do tại sao tôi gửi câu trả lời của mình. –

2

Vấn đề của bạn là cách bạn liên kết ReleaseItemPack.

has_many :throughhas_one :through cả hai đều hoạt động thông qua một đối tượng cũng hoạt động như một bảng tham gia, trong trường hợp này là PackReleaseItem. Vì đây không chỉ là một bảng tham gia (nếu nó là, bạn chỉ nên sử dụng has_many mà không :through), đúng cách tạo liên kết đòi hỏi phải tạo ra các đối tượng tham gia, như vậy:

>> item.pack_release_items.create :pack => pack 

gì bạn đang làm với item.pack = pack của bạn cuộc gọi chỉ đơn giản là liên kết các đối tượng trong bộ nhớ. Khi bạn tìm lại nó, có vẻ như "through" là pack_release_items, trống.

+0

>> item.pack_release_items.create: pack => gói => # >> item.pack => nil – lordscarlet

+0

Điều đó có thể xảy ra vì gói không đáp ứng tất cả các trình xác nhận hợp lệ. Tôi sẽ thử lại khi tôi về nhà. – lordscarlet

+0

Gói không nằm ở trên trong ví dụ của bạn vì Gói chưa được lưu - bạn có thể thấy "pack_id: nil" trong PackReleaseItem của mình. –

1

Bạn muốn lưu hoặc tạo (thay vì mới) mục và gói. Nếu không, cơ sở dữ liệu chưa gán id cho liên kết.

Các vấn đề liên quan