Adding :default => true to boolean in existing Rails column

tvalent2 picture tvalent2 · Dec 24, 2011 · Viewed 129.7k times · Source

I've seen a few questions (namely this one) here on SO about adding a default boolean value to an existing column. So I tried the change_column suggestion but I mustn't be doing it right.

I tried:

$ change_column :profiles, :show_attribute, :boolean, :default => true

Which returns -bash: change_column: command not found

I then ran:

$ rails g change_column :profiles, :show_attribute, :boolean, :default => true

...and

$ rails change_column :profiles, :show_attribute, :boolean, :default => true

Then ran rake db:migrate, but the value for :show_attribute remained nil. In the question I referenced above it says in PostgreSQL you need to update it manually. Since I'm using PostgreSQL I added the following in my create_profiles migration:

t.boolean :show_attribute, :default => true

Can someone tell me what I'm doing wrong here?

Answer

Robin picture Robin · Dec 24, 2011

change_column is a method of ActiveRecord::Migration, so you can't call it like that in the console.

If you want to add a default value for this column, create a new migration:

rails g migration add_default_value_to_show_attribute

Then in the migration created:

# That's the more generic way to change a column
def up
  change_column :profiles, :show_attribute, :boolean, default: true
end

def down
  change_column :profiles, :show_attribute, :boolean, default: nil
end

OR a more specific option:

def up
    change_column_default :profiles, :show_attribute, true
end

def down
    change_column_default :profiles, :show_attribute, nil
end

Then run rake db:migrate.

It won't change anything to the already created records. To do that you would have to create a rake task or just go in the rails console and update all the records (which I would not recommend in production).

When you added t.boolean :show_attribute, :default => true to the create_profiles migration, it's expected that it didn't do anything. Only migrations that have not already been ran are executed. If you started with a fresh database, then it would set the default to true.