Create association between two instancied objects
Asked Answered
L

2

9

I have two models: (Albums and Product)

1) Inside Models

Inside album.rb:

class Album < ActiveRecord::Base
  attr_accessible :name
  has_many :products
end

Inside product.rb:

class Product < ActiveRecord::Base
  attr_accessible :img, :name, :price, :quantity
  belongs_to :album
end

2) Using "rails console", how can I set the associations (so I can use "<%= Product.first.album.name %>")?

e.g.

a = Album.create( :name => "My Album" )
p = Product.create( :name => "Shampoo X" )
# what's next? how can i set the album and the product together?
Leavetaking answered 26/12, 2012 at 0:1 Comment(0)
S
12

You can do like this:

a = Album.create( name: "My Album" )

p = Product.create( name: "Shampoo X" )
# OR
p = Product.create( name: "Shampoo X", album_id: a.id )
# OR
p.album = a
# OR
p.album_id = a.id
# OR 
a.products << a
# finish with a save of the object:
p.save

You may have to set the attribute accessible to album_id on the Product model (not sure about that).

Check @bdares' comment also.

Sprinkling answered 26/12, 2012 at 0:4 Comment(6)
If you add the _id to accessible, then you can just stick the id value as you instantiate it: Product.create(name:'Shampoo',album_id:a.id)Expedition
@bdares To add _id, I just have to use attr_accessible :img, :name, :price, :quantity, :_id, right? However, it gives me this error, ActiveModel::MassAssignmentSecurity::Error: Can't mass-assign protected attributes: album_idLeavetaking
@MrYoshiji, For p.album = a, it temporarily works, but if I reopen the console, the p.album turns into "nil". For p.album_id = a.id, it gives this error, NoMethodError: undefined method 'album_id='. For a.products << p, it gives this error, RuntimeError: can't modify frozen Hash. Do I need to regenerate both models? Thank you everyone!Leavetaking
You have to give access to the album_id attribute: attr_accessible :img, :name, :price, :quantity, :album_idSprinkling
Thanks! Apparently, I have to recreate the Product Model to have album_id:integer, not just add it in attr_accessible.Leavetaking
Yes you have to generate a migration (api.rubyonrails.org/classes/ActiveRecord/Migration.html) in order to add the new column album_id as integer in the database.Sprinkling
B
2

Add the association when you create the Product:

a = Album.create( :name => "My Album" )
p = Product.create( :name => "Shampoo X", :album => a )
Brantbrantford answered 26/12, 2012 at 0:28 Comment(2)
It temporarily works. However, if I reopen the console, the p.album turns into "nil"..Leavetaking
Are you fetching the same Product you created the first time? Try the above code, then reopen the console and try Product.find_by_name('Shampoo X').album.Brantbrantford

© 2022 - 2024 — McMap. All rights reserved.