在 Rails Active Record 迁移中添加一列,其初始值基于其他列
Add a column in a Rails Active Record migration with an initial value based on other columns
我正在尝试使用 Rails 中的 Active Record 迁移向现有 table 添加一列。我需要该列的初始值基于 table 中的其他列。有没有办法在 Active Record 迁移中做到这一点?
为了更具体,假设我有以下内容:
my_table
----------------
first_name: text
last_name: text
我想添加初始值为 concat(first_name, ' ', last_name'
的 full_name
文本列。请注意,我不想在该列上使用默认值,因为我打算让应用程序继续填充此值(初始默认值只是为现有记录提供一个合理的起始值)。
如何在迁移中执行此操作?理想情况下,我想使用 add_column
或类似的,但如果那行不通,则可行的替代方法是 acceptable.
请注意,已经存在一个几乎相同的问题 (add a database column with Rails migration and populate it based on another column),但 none 的答案似乎完全回答了这个问题。
您可以在 add_column
之后使用 update_all
。对于 MySQL:
Person.update_all('full_name = concat(first_name, " ", last_name)')
我最终使用 add_column
添加了列,然后直接使用 SQL 更新了列的值。我直接使用 SQL 而不是每个 this answer 的模型,因为它不依赖于模型的当前状态与基于迁移的 table 的当前状态 运行.
class AddFullName < ActiveRecord::Migration
def up
add_column :my_table, :full_name, :text
execute "update my_table set full_name = concat(first_name, ' ', last_name)"
end
def down
remove_column :my_table, :full_name
end
end
就是说,如果有更好或更惯用的方法来解决这个问题,我会洗耳恭听。
我正在尝试使用 Rails 中的 Active Record 迁移向现有 table 添加一列。我需要该列的初始值基于 table 中的其他列。有没有办法在 Active Record 迁移中做到这一点?
为了更具体,假设我有以下内容:
my_table
----------------
first_name: text
last_name: text
我想添加初始值为 concat(first_name, ' ', last_name'
的 full_name
文本列。请注意,我不想在该列上使用默认值,因为我打算让应用程序继续填充此值(初始默认值只是为现有记录提供一个合理的起始值)。
如何在迁移中执行此操作?理想情况下,我想使用 add_column
或类似的,但如果那行不通,则可行的替代方法是 acceptable.
请注意,已经存在一个几乎相同的问题 (add a database column with Rails migration and populate it based on another column),但 none 的答案似乎完全回答了这个问题。
您可以在 add_column
之后使用 update_all
。对于 MySQL:
Person.update_all('full_name = concat(first_name, " ", last_name)')
我最终使用 add_column
添加了列,然后直接使用 SQL 更新了列的值。我直接使用 SQL 而不是每个 this answer 的模型,因为它不依赖于模型的当前状态与基于迁移的 table 的当前状态 运行.
class AddFullName < ActiveRecord::Migration
def up
add_column :my_table, :full_name, :text
execute "update my_table set full_name = concat(first_name, ' ', last_name)"
end
def down
remove_column :my_table, :full_name
end
end
就是说,如果有更好或更惯用的方法来解决这个问题,我会洗耳恭听。