M. Justin
M. Justin

Reputation: 21189

Add a column in a Rails Active Record migration with an initial value based on other columns

I am attempting to add a column to an existing table using an Active Record migration in Rails. I need the column's initial value to be based on other columns in the table. Is there a way to do this in an Active Record migration?

To make it more concrete, let's say I have the following:

my_table
----------------
first_name: text
last_name: text

I want to add a full_name text column with an initial value of concat(first_name, ' ', last_name'. Note that I don't want a default value on the column, as I intend for the application to be populating this going forward (the initial default is just to have a sensible starting value for existing records).

How can I do this in a migration? Ideally I would like to use add_column or similar, though if that can't work a working alternative would be acceptable.

Note that there already exists a nearly identical question (add a database column with Rails migration and populate it based on another column), but none of its answers seem to fully answer this question.

Upvotes: 1

Views: 2315

Answers (2)

M. Justin
M. Justin

Reputation: 21189

I ended up adding the column using add_column and then using direct SQL to update the value of the column. I used direct SQL and not the model per this answer, since then it doesn't depend on the current state of the model vs. the current state of the table based on migrations being run.

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

That said, if there is a better or more idiomatic approach to this, I'm all ears.

Upvotes: 1

Danil Speransky
Danil Speransky

Reputation: 30463

You could use update_all after add_column. For MySQL:

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

Upvotes: 2

Related Questions