My new rails 4.1 project has the following polymorphic associations.
class Order < ActiveRecord::Base
has_many :line_items, as: :line_itemable
end
class LineItem < ActiveRecord::Base
belongs_to :line_itemable, polymorphic: true
end
class Shipment < ActiveRecord::Base
has_many :line_items, as: :line_itemable
end
I am trying to migrate some old data so I have in my seeds.rb file
neworder = Order.create do |order|
...
end
neworder.line_items << LineItem.create do |li|
...
end
The << has always worked for me in the past. In my old system I didn't have the shipments class so I had
class Order < ActiveRecord::Base
has_many :line_items
end
class LineItem < ActiveRecord::Base
belongs_to :order
end
and << just worked. Now, I have been able to make the migration work by using
neworder = Order.create do |order|
...
end
newlineitem = LineItem.create do |li|
...
end
newlineitem.update_attribute(:line_itemable, neworder)
This just does not seem like the rails way to do things. Am I doing something wrong?
The problem is that in migration you do not use class from app/models, but the one inside your migration. Check via
rails console
what's in theline_itemable_type
column for chosenLineItem
. Instead ofOrder
you will seeYourMigrationName::Order
, which explains everything.In general your approach is correct though - it is good practice to define code in migration if it requires it to work. There is just one gotcha with polymorphic association :) I think there is no 'best' way to deal with it - one can set
type
manually (this is what I would have done), one can craft sql query manually (if you need to create a lot of objects this is probably the way to go, but then shouldn't be placed in migration IMO). You can for example set type like this:newlineitem = LineItem.create do |li| li.line_itemable_type = 'Order' li.line_itemable_id = neworder.id # other stuff you have end