在Rails Active Record迁移中添加一列,其中包含基于其他列的初始值

时间:2017-09-20 18:37:34

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

我正在尝试使用Rails中的Active Record迁移向现有表添加列。我需要列的初始值基于表中的其他列。有没有办法在Active Record迁移中执行此操作?

为了使其更具体,让我说我有以下内容:

int i=st.executeUpdate("update tbl_loginprogrammer1
               JOIN tbl_loginprogrammer
               ON tbl_loginprogrammer1.pid = tbl_loginprogrammer.proid
        SET    tbl_loginprogrammer1.assigned = 'project3'
        where pid=(select min(proid) from tbl_loginprogrammer where planguage='java' and status='finished')");

我想添加一个my_table ---------------- first_name: text last_name: text 文本列,其初始值为full_name。请注意,我不希望列上有默认值,因为我打算让应用程序继续填充(初始默认值只是为现有记录提供合理的起始值)。

如何在迁移中执行此操作?理想情况下,我想使用concat(first_name, ' ', last_name'或类似的,但如果不能正常工作,那么可以接受。

请注意,已存在几乎相同的问题(add a database column with Rails migration and populate it based on another column),但其答案似乎都没有完全回答这个问题。

2 个答案:

答案 0 :(得分:1)

您可以在update_all之后使用add_column。对于MySQL:

Person.update_all('full_name = concat(first_name, " ", last_name)')

答案 1 :(得分:1)

我最后使用add_column添加列,然后使用直接SQL更新列的值。我使用直接SQL而不是每this answer的模型,因为它不依赖于模型的当前状态与基于正在运行的迁移的表的当前状态。

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

那就是说,如果有更好或更惯用的方法,我会全力以赴。