rails polymorphic add using <<

205 views Asked by At

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?

1

There are 1 answers

0
mkk On BEST ANSWER

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 the line_itemable_type column for chosen LineItem. Instead of Order you will see YourMigrationName::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