我有一个模型(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任务,还是有办法通过迁移来实现?
答案 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