在 Rails 迁移中将一列更新为另一列的值 [英] Update one column to value of another in Rails migration
问题描述
我在 Rails 应用程序中有一个包含数十万条记录的表,它们只有一个 created_at
时间戳.我正在添加编辑这些记录的功能,因此我想向表中添加一个 updated_at
时间戳.在我添加列的迁移中,我想更新所有行以使新的 updated_at
与旧的 created_at
匹配,因为这是 Rails 中新创建的行的默认设置.我可以执行 find(:all)
并遍历记录,但由于表的大小,这需要几个小时.我真正想做的是:
I have a table in a Rails app with hundreds of thousands of records, and they only have a created_at
timestamp. I'm adding the ability to edit these records, so I want to add an updated_at
timestamp to the table. In my migration to add the column, I want to update all rows to have the new updated_at
match the old created_at
, since that's the default for newly created rows in Rails. I could do a find(:all)
and iterate through the records, but that would take hours because of the size of the table. What I really want to do is:
UPDATE table_name SET updated_at = created_at;
在使用 ActiveRecord 而不是执行原始 SQL 的 Rails 迁移中,有没有更好的方法来做到这一点?
Is there a nicer way to do that in a Rails migration using ActiveRecord rather than executing raw SQL?
推荐答案
我会创建一个迁移
rails g migration set_updated_at_values
在里面写一些类似的东西:
and inside it write something like:
class SetUpdatedAt < ActiveRecord::Migration
def self.up
Yourmodel.update_all("updated_at=created_at")
end
def self.down
end
end
这样你就实现了两件事
- 这是一个可重复的过程,每个可能的部署(在需要的地方)都会执行
- 这很有效率.我想不出更像红宝石般的解决方案(效率一样高).
注意:如果使用 activerecord 编写查询太难,您也可以在迁移中运行原始 sql.只需编写以下内容:
Note: you could also run raw sql inside a migration, if the query gets too hard to write using activerecord. Just write the following:
Yourmodel.connection.execute("update your_models set ... <complicated query> ...")
这篇关于在 Rails 迁移中将一列更新为另一列的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!