2012-01-08 31 views
6

Tôi có tài nguyên Mục và tài nguyên Chủ sở hữu.Làm cách nào để tạo một đối tượng mới tham chiếu thuộc tính lồng nhau hiện có?

rails g scaffold Item name:string 
rails g scaffold Owner name:string 

class Item < ActiveRecord::Base 
    has_one :owner 
    accepts_nested_attributes_for :owner 
end 

class Owner < ActiveRecord::Base 
    belongs_to :item 
end 

Vấn đề của tôi là tôi không thể tạo đối tượng Mục mới tham chiếu đối tượng Chủ sở hữu hiện tại.

In /db/migrate/create_owners.rb 
def self.up 
    ... 
    t.integer :item_id 
end 

rake db:migrate 
rails c 

ruby-1.9.2-p0 > o= Owner.create(:name => "Test") 
=> #<Owner id: 1, name: "Test", created_at: "...", updated_at: "..."> 

ruby-1.9.2-p0 > i= Item.create(:owner_attributes => {"id" => Owner.last.id.to_s}) 
ActiveRecord::RecordNotFound: Couldn't find Owner with ID=1 for Item with ID= 

Tôi biết rằng Item.create(:owner_id => "1") sẽ hoạt động trong trường hợp này, nhưng tiếc là đây không phải là giải pháp khả thi trong ứng dụng của tôi. Điều này là do tôi đang thêm và xóa các thuộc tính lồng nhau khi đang bay và, ví dụ, cần phải tạo một đối tượng Item mới với một đối tượng Owner hiện có và một đối tượng Owner mới.

tôi tìm thấy những liên kết này nhưng không thể tìm ra nếu điều này là một tính năng hay một lỗi trong đường ray:
https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id-is-specified
http://osdir.com/ml/RubyonRails:Core/2011-05/msg00001.html

ai đó có thể cho tôi một ý tưởng như thế nào tôi có thể làm công việc này hoặc tôi đã hiểu sai cách đúng để sử dụng 'accept_nested_attributes_for' ??

Tôi đang sử dụng Rails 3.0.5 và Ruby 1.9.2p0.

Xin cảm ơn trước.

Trả lời

1

Khi bạn cố gắng để tạo ra một Item với id chủ sở hữu trong các thuộc tính lồng nhau, nó nói với ActiveRecord để cập nhật một bản ghi hiện Owner. ActiveRecord không thể tìm thấy bản ghi chủ sở hữu vì không có giá trị khóa ngoài hiện có (id cho bản ghi mục vẫn là nil).

Item.create(:owner_attributes => {"id" => Owner.last.id.to_s}) 
#=> ActiveRecord::RecordNotFound: Couldn't find Owner with ID=1 for Item with ID= 

Hãy thử đổi has_one/depends_to associtaions và di chuyển khóa ngoại vào bảng mục. Sau đó, bạn có thể đặt khóa ngoài trong mô hình gốc (không lồng nhau) và vẫn sử dụng các thuộc tính lồng nhau.

class Item < ActiveRecord::Base 
    belongs_to :owner 
    accepts_nested_attributes_for :owner 
end 

class Owner < ActiveRecord::Base 
    has_one :item 
end 

owner = Owner.create 

Item.create(:owner_id => owner.id, :owner_attributes => {"id" => owner.id, ...}) 
#=> Works!!! Note that the owner id is used twice. With some work you could probably set the id in one place or the other. 
+0

Cảm ơn! Tôi đã không làm việc trên dự án này trong hơn một năm, nhưng câu trả lời của bạn có ý nghĩa. Tôi sẽ thử nó (không quan tâm) khi tôi có một chút thời gian. –

0

accepts_nested_attributes_for chỉ được sử dụng cho các liên kết has_onehas_many. (xem http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html không thuộc về_to) Nó được gọi là 'lồng nhau' nên không có nhiều trợ giúp ở đó. Có lẽ refactor ứng dụng của bạn?

Cụ thể là trường hợp lỗi bạn gặp phải là vì nó hy vọng rằng phụ huynh sẽ có thể tìm thấy mô hình lồng nhau, cho id của mô hình lồng nhau. I E.

parent.nested_model.find(id) 

Nó có vẻ như, về cơ bản để ngăn chặn từ việc cập nhật mô hình đứa trẻ đó không thuộc về phụ huynh

+0

Cảm ơn. Tôi đã thay đổi ví dụ để sử dụng has_one. Thật không may, vấn đề vẫn tồn tại. Có cách nào để đạt được những gì tôi đang cố gắng hay không, hay tôi là tốt nhất khi quay trở lại bảng vẽ? –

+0

Không đúng sự thật, nó sẽ làm việc cho thuộc về, không chỉ là một ví dụ về nó ở đó. Nếu has_one hoạt động, thuộc tính sẽ hoạt động. –

+0

@RyanBigg hmm, tôi phải đọc sai cách hoạt động lồng nhau. yeah 'thuộc_to' nên được làm việc nếu has_one hoạt động. @Jack không có vẻ như đó là một vấn đề như liên kết ngọn hải đăng (https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id- được chỉ định # ticket-4254-6) mà bạn đã đăng. –

2

tôi giải quyết vấn đề một cách khác và muốn gửi một phiên bản đơn giản của nó ở đây trong trường hợp nó giúp bất cứ ai khác. Trong ứng dụng thực sự của tôi, sự kết hợp giữa hai tài nguyên là HABTM và tài nguyên lồng nhau là một tệp đính kèm.

Vì vậy, trong hành động tạo của bộ điều khiển, tôi tách các tham số cho tài nguyên gốc và các tham số cho tài nguyên lồng nhau.

Sau đó tôi tách riêng tài nguyên lồng nhau thành các đối tượng tồn tại trong cơ sở dữ liệu và các đối tượng không, đặt id của những người làm vào mảng.

Nếu không có đối tượng lồng nhau hiện có nào, thì đó là hành trình đơn giản từ đây.

Tuy nhiên, giả sử cả hai đối tượng lồng nhau hiện có và mới được trình bày, tôi tạo ra một đối tượng mục mới như sau:
@item = Item.new(:attachment_ids => existing_attachment_ids)

Sau đó tôi cập nhật @item như sau:
@item.update_attributes(original_item_params)
@item.update_attributes(params_for_new_nested_objects)

Sau đó, bạn có thể gọi @item.save và yêu cầu hiển thị lại chế độ xem nếu có bất kỳ lỗi nào xảy ra.

Tôi vẫn không thể tìm ra nếu đây là lỗi hoặc tính năng ir Rails.Nếu bất cứ ai có bất kỳ suy nghĩ về chủ đề hoặc giải pháp của tôi, tôi sẽ rất vui khi nghe họ.

+0

Chỉ cần thông tin, xem thêm vé Rails cũ này: https://rails.lighthouseapp.com/projects/8994/tickets/4254-assigning-nested-attributes-fails-for-new-object-when-id-is-specified –

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