315

How do I add a default value to a column that already exists through a migration?

All the documentation I can find shows you how to do it if the column doesn't already exist but in this case it does.

Jon
  • 3,905
  • 5
  • 26
  • 22

7 Answers7

399

Here's how you should do it:

change_column :users, :admin, :boolean, :default => false

But some databases, like PostgreSQL, will not update the field for rows previously created, so make sure you update the field manaully on the migration too.

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
207
change_column_default :employees, :foreign, false
Soviut
  • 88,194
  • 49
  • 192
  • 260
Gazza
  • 3,051
  • 1
  • 20
  • 22
  • 1
    @DenisLins I agreed with you, so I did some research to figure out why it might not be, and it turns out there's a possibility that a particular database adapter doesn't support it, as it's implemented at that level. The accepted answer is still the safest bet until it's implemented in the abstract model. http://apidock.com/rails/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/SchemaStatements/change_column_default – natchiketa Jul 21 '15 at 14:54
  • 8
    Besides that, you need to specify a `from:` and `to:` if you want it to be reversible :) – radubogdan Mar 27 '17 at 11:34
  • 8
    **Using `from` and `to` was added in Rails 5+ in this commit: https://github.com/rails/rails/pull/20018/files** – Joshua Pinter Dec 29 '18 at 19:03
148

For Rails 4+, use change_column_default

def change
  change_column_default :table, :column, value
end
davegson
  • 8,205
  • 4
  • 51
  • 71
csi
  • 9,018
  • 8
  • 61
  • 81
  • 1
    This is great especially if you have a migration that is adding a column and setting defaults for existing records. For example: `def change` ` add_column :foos, :name, default: "something for existing values"` ` change_column_default :foos, :name, default: ""` `end` – user1491929 Jan 04 '16 at 16:14
  • 8
    This migration have a strange behaviour. In yours example it's irreversible. http://edgeguides.rubyonrails.org/active_record_migrations.html recommend to use it this way: `change_column_default :products, :approved, from: true, to: false` — but it doesn't works too. – Ilya Krigouzov May 13 '16 at 17:06
  • can't rollback using that? – aldrien.h Feb 27 '18 at 11:39
  • Usually so yes, for almost any "Change" clause, since all previous states are usually explicit, such as the presence of a column, it's type, etc. The change can be rolled back as it's shown there if and only if there was a valid explicit default previously. Since it's common that defaults are undefined, you might have an issue there. – Elindor Dec 16 '19 at 21:30
59

Using def change means you should write migrations that are reversible. And change_column is not reversible. You can go up but you cannot go down, since change_column is irreversible.

Instead, though it may be a couple extra lines, you should use def up and def down

So if you have a column with no default value, then you should do this to add a default value.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: nil
end

Or if you want to change the default value for an existing column.

def up
  change_column :users, :admin, :boolean, default: false
end

def down
  change_column :users, :admin, :boolean, default: true
end
bfcoder
  • 3,042
  • 2
  • 28
  • 35
54

**Rails 4.X +**

As of Rails 4 you can't generate a migration to add a column to a table with a default value, The following steps add a new column to an existing table with default value true or false.

1. Run the migration from command line to add the new column

$ rails generate migration add_columnname_to_tablename columnname:boolean

The above command will add a new column in your table.

2. Set the new column value to TRUE/FALSE by editing the new migration file created.

class AddColumnnameToTablename < ActiveRecord::Migration
  def change
    add_column :table_name, :column_name, :boolean, default: false
  end
end

**3. To make the changes into your application database table, run the following command in terminal**

$ rake db:migrate
James Bush
  • 133
  • 1
  • 9
Praveen George
  • 9,237
  • 4
  • 26
  • 53
  • How is this any different to rails 3+ or 2+? – Ruby Racer Feb 06 '16 at 16:05
  • 3
    Does anyone know if this has been incorporated into Rails 5? – sambecker Sep 01 '16 at 17:23
  • @sambecker I know I might be a little late replying to your comment, but it's working for me on Rails 6.0.3.1 – Mathyou Aug 16 '20 at 15:16
  • @Mathyou good to know. In Rails 6 can a new table have columns with default values? Or is still a separate migration? – sambecker Aug 17 '20 at 16:20
  • @sambecker you can definitely set default values in the new table migration. One of my columns in such a migration looks like: `t.boolean :is_active, :null => false, :default => false` – Mathyou Jan 14 '21 at 01:13
11

Execute:

rails generate migration add_column_to_table column:boolean

It will generate this migration:

class AddColumnToTable < ActiveRecord::Migration
  def change
    add_column :table, :column, :boolean
  end
end

Set the default value adding :default => 1

add_column :table, :column, :boolean, :default => 1

Run:

rake db:migrate

axeltaglia
  • 2,543
  • 1
  • 13
  • 5
  • 3
    Now the default value of 1 is not exactly a boolean ;) Also, this exampe *adds* a new column, instead of changing the existing column, which is what the OP wanted to achieve – radiospiel Sep 04 '13 at 11:18
  • @radiospiel Actually, 1 is a boolean too :) – kinduff Nov 12 '13 at 01:32
  • You will also need to create a record in the foreign key table with an ID of 1 for this to work, to avoid the `Key is not present in table error`. – Promise Preston Mar 21 '20 at 12:40
-61

This is what you can do:

class Profile < ActiveRecord::Base
  before_save :set_default_val

  def set_default_val
    self.send_updates = 'val' unless self.send_updates
  end
end

EDIT: ...but apparently this is a Rookie mistake!

rmcsharry
  • 5,363
  • 6
  • 65
  • 108
rookieRailer
  • 2,313
  • 2
  • 28
  • 48