如何在现有记录(历史数据)上进行rails迁移?

时间:2017-06-20 11:50:39

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

我有一个模型(Model_A),有两列(Column_A和Column_B)

我的模型中有以下方法,两个基于column_A生成column_B的值

Class Model_A < ActiveRecord::Base
  before_save :set_column_B

  def set_column_B
      self.column_B = get_value_from_column_A
  end

  def get_value_from_column_A
    # manipulate data from A to get value
    column_A.join(,) 
  end

end

我知道我必须创建一个新的column_B作为迁移的第一步,但是如何更改数据库中所有预先存在的记录以使其在column_B中具有正确的值? 我应该为此编写脚本或Rake任务,还是有办法通过迁移来实现?

2 个答案:

答案 0 :(得分:1)

如果你有很多记录,那么循环所有记录是一个坏主意。让我们假设您有200万条记录如果您要ActiveRecord方式,那么更新列然后执行回调和验证需要永远。

如果您可以使用SQL本身,则可以使用SQL方式

更新所有记录

像Spree

这样的迁移
class UpdateNameFieldsOnSpreeCreditCards < ActiveRecord::Migration
  def up
    if ActiveRecord::Base.connection.adapter_name.downcase.include? "mysql"
      execute "UPDATE spree_credit_cards SET name = CONCAT(first_name, ' ', last_name)"
    else
      execute "UPDATE spree_credit_cards SET name = first_name || ' ' || last_name"
    end
  end

  def down
    execute "UPDATE spree_credit_cards SET name = NULL"
  end
end

答案 1 :(得分:0)

在迁移中,您可以执行以下操作:

 class AddColummBToModelA < ActiveRecord::Migration
  def up
    unless column_exists? :budgets, :column_b
      add_column :budgets, :column_b ......
      ModelA.find_each {|x| x.save! }
    end

  end

  def down
   remove_column :budgets, :column_b if column_exists? :budgets, :column_b
  end
end