I have an Item resource and an Owner resource.
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
My problem is that I cannot create a new Item object referencing an existing Owner object.
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=
I am aware that Item.create(:owner_id => "1")
would work in this case, but unfortunately this not a viable solution in my app. This is because I am adding and deleting nested attributes on the fly and, for example, need to create a new Item object with one existing Owner object and one new Owner object.
I found these links but couldn't work out if this is a feature or a bug in rails:
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
Can somebody give me an idea as to how I can make this work or have I misunderstood the correct way to use 'accepts_nested_attributes_for'??
I am using Rails 3.0.5 and Ruby 1.9.2p0.
Thanks in advance.
Nested attributes are a way of applying sub-categories to your attributes. For instance, instead of having a single searchable attribute price , you may set up some sub-categories: price.net , price. gross , price. margin (note the use of 'dot notation' here to separate the parent attribute from its child).
accepts_nested_attributes_for(*attr_names) public. Defines an attributes writer for the specified association(s). Supported options: :allow_destroy. If true, destroys any members from the attributes hash with a _destroy key and a value that evaluates to true (eg.
I solved the problem another way and wanted to post a simplified version of it here in case it helps anyone else. In my real app the assosciation between both resources is HABTM and the nested resource is a file attachment.
So, in the create action of the controller, I separate the parameters for the original resource and those for the nested resource.
I then further separate the nested resource into objects which exist in the database and objects which don't, putting the ids of those which do into an array.
If no existing nested objects are present, then it's plain sailing from here.
However, presuming both existing and new nested objects are present, I create a new Item object thus:@item = Item.new(:attachment_ids => existing_attachment_ids)
After that I update @item thus: @item.update_attributes(original_item_params)
@item.update_attributes(params_for_new_nested_objects)
Then you can call @item.save
and have it re-render the view if any errors occur.
I still can't work out if this is a bug or a feature ir Rails. If anyone has any thoughts on the subject or my solution, I would be very glad to hear them.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With