如何在添加多态关联后迁移现有数据?

时间:2017-02-28 15:30:15

标签: ruby-on-rails ruby-on-rails-4 activerecord rails-migrations

迁移后,我的PageViewStats表包含2个新的空列: ad_templatable_idad_templatable_type。因此,如果我尝试查询现有记录,如下所示:AdTemplate.find(42).page_view_stats它不返回任何内容,但在迁移之前它会返回PageViewStats个记录的数组。

我想我需要创建一个rake任务,用这两个新列填充:

1)ad_templatable_id将包含现有ad_template_id

中的值

2)ad_templatable_type将包含字符串AdTemplate

我的猜测是对的吗? :)这是我需要做的吗?

迁移前:

# == Schema Information
# #  ad_template_id      :integer          not null
class PageViewStat < ActiveRecord::Base
  belongs_to :ad_template
end

class AdTemplate < ActiveRecord::Base
  has_many :page_view_stats
end

应用多态迁移:

class AddPolymorphismToPageViewStat < ActiveRecord::Migration
  def change
    add_reference :page_view_stats, :ad_templatable, polymorphic: true
    add_index :page_view_stats, [:ad_templatable_type, :ad_templatable_id],
               name: 'index_page_view_stats_on_ad_templatable_type_and_id'
  end
end

迁移后:

# == Schema Information
# #  ad_template_id      :integer          not null
class PageViewStat < ActiveRecord::Base
  belongs_to :ad_templatable, polymorphic: true
end

class AdTemplate < ActiveRecord::Base
  has_many :page_view_stats, as: :ad_templatable
end

1 个答案:

答案 0 :(得分:1)

是的,创建rake任务比手动执行数据迁移更好,因为你可以为它编写测试。

另一种方法是包含代码来更改迁移中的数据,这对于确保在架构更改时迁移数据非常有用,从而减少了潜在的停机时间,例如

def up
  [code to add new columns]

  migrate_data

  [code to remove legacy columns]
end

def down
  [code to add legacy columns]

  rollback_data

  [code to remove new columns]
end

private

def migrate_data
  [code to make data changes]
end

def rollback_data
  [code to reverse data changes]
end

注意,如果你这样做,有一些问题,你需要单独指定向上和向下迁移,你应该完成编写代码以进行回滚和测试的工作。