如何在Rails迁移中安全地使用多态模型?

时间:2011-12-15 21:38:38

标签: ruby-on-rails migration polymorphic-associations

我理解,如果您在迁移期间操作模型数据,那么在迁移中定义模型是最佳做法。但是,当我尝试使用多态关联build_other时,polymorphic_type属性将模型命名为我已声明的迁移模型,导致结果数据集不真正关联。

基本上,我最终得到的地址是将addressable_type设置为“RemoveAddressColumnsFromEmployeesTable :: Employee”而不仅仅是“Employee”。

我可以通过显式设置addressable_type和addressable_id来解决这个问题,但这是处理这种封装的唯一方法吗?

class RemoveAddressColumnsFromEmployeesTable < ActiveRecord::Migration

  class Employee < ActiveRecord::Base
    has_one :address, :as => :addressable, :inverse_of => :addressable
  end

  class Address < ActiveRecord::Base
    belongs_to :addressable, :polymorphic => true, :inverse_of => :address
  end

 def up
   Employee.all.each do |e|
     address                = e.build_address
     address.street_address = e.street_address
     address.apt_num        = e.apt_num
     address.city           = e.city
     address.state          = e.state
     address.zip            = e.zip
     e.save
   end

   remove_column :employees, :street_address
   remove_column :employees, :apt_num
   remove_column :employees, :city
   remove_column :employees, :state
   remove_column :employees, :zip
 end

 def down
   add_column :employees, :street_address, :string
   add_column :employees, :apt_num,        :string
   add_column :employees, :city,           :string
   add_column :employees, :state,          :string
   add_column :employees, :zip,            :string                                                                                                             

   Employee.all.each do |e|
     e.street_address = e.address.street_address
     e.apt_num        = e.address.apt_num
     e.city           = e.address.city
     e.state          = e.address.state
     e.zip            = e.address.zip
     e.address = nil
     e.save
   end
 end
end

1 个答案:

答案 0 :(得分:0)

我找到了安排我的决定。在你的情况下,这意味着在下一个上取代多态关联:

  class Employee < ActiveRecord::Base
    has_one :address, :foreign_key => :addressable_id, :conditions => {:addressable_type => 'Employee'}
  end

  class Address < ActiveRecord::Base
    belongs_to :addressable, :polymorphic => true
  end