将表数据迁移到另一个表的最佳方法

时间:2013-04-18 13:05:37

标签: mysql ruby-on-rails migration ruby-on-rails-2

考虑4个模型(非常简化)

class Group1 << AR::Base
  has_many group1_items
end
class Group2 << AR::Base
  has_many group2_items
end

class GroupItem << AR::Base
  belongs_to :group1
  belongs_to :thing
end
class Group2Item << AR::Base
  belongs_to :group2
  belongs_to :thing
end

我想将Group2和Group2Items“合并”到Group1和Group1Items。 Group2将继承Group1。我想要的是什么:

class Group2 << Group1

Group2Item模型将被使用。

我需要创建一个迁移,将Group2和Group2Items数据“移动”到Group1和Group1Item表。

无论应用程序状态如何,我的迁移都必须是可访问的,即Group2和Group2Item表不能出现,所以我需要在mySQL语法中执行此操作。

有一种简单的方法吗?

1 个答案:

答案 0 :(得分:1)

def up
  change_table :group1s do |t|
    t.string :type       # add a 'type' column for STI
    t.integer :old_id    # add a temporary column to hold the original 'id'
  end

  execute("UPDATE group1s SET `type` = 'Group1';")

  merge_items_sql = <<SQL
    INSERT INTO group1s (`type`, old_id, other_field_names...) 
    SELECT 'Group2', group2s.id, other_field_values...
    FROM group2s;

    INSERT INTO group1_items(group1_id, thing_id )
    SELECT group1s.id, group2_items.thing_id
    FROM group2_items
    JOIN group1s ON group2_items.group2_id = group1s.old_id;
SQL

  execute(merge_items_sql)

  # leave this out until you have verified that all data has merged properly
  drop_table :group2_items
  drop_table :group2s
  remove_column :group1s, :old_id
end