51

Given the following schema.rb:

  create_table "people", force: true do |t|
    t.string   "name",  null: false
    t.integer  "age"
    t.integer  "height"
    t.string   "email"
    t.boolean  "married",  default: false
    t.text     "bio"
    t.integer  "fav_number"
    t.decimal  "lucky_num",  precision: 2, scale: 2
    t.datetime "birthday"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

I'd like to remove the name default value of null: false. I've tried running a separate migration with change_column_default, but that had no impact on schema.rb. Any suggestions?

atw
  • 5,428
  • 10
  • 39
  • 63
gabethegrape
  • 681
  • 1
  • 6
  • 11

4 Answers4

69

From the docs:

  def up
    change_column_default :table_name, :status, 0
  end

  def down
    change_column_default :table_name, :status, nil
  end
D-side
  • 9,150
  • 3
  • 28
  • 44
luigi7up
  • 5,779
  • 2
  • 48
  • 58
  • 2
    I think you meant to write `:table_name` instead of `:column_name` for that first value. `change_column_default(table_name, column_name, default) public` – trueinViso Mar 18 '15 at 17:12
29

The 'up' function will definitely do the job when you do db:migrate.
But in the future, in some cases, like rollback, you might want a function to reverse this particular migration.

def up
  change_column_null :people, :name, true
end

def down
  change_column_null :people, :name, false
end
ran632
  • 1,099
  • 1
  • 12
  • 14
  • 2
    While this code may answer the question, it would be better to explain how it solves the problem and why to use it. Code-only answers are not useful in the long run. – Tobias Liefke Nov 19 '15 at 20:02
  • Can you add an explanation as well, what is the difference to [this answer](http://stackoverflow.com/questions/23098047/change-default-value-for-table-column-with-rails-migrations-rails-4/27266641#27266641)? – Tobias Liefke Nov 22 '15 at 13:22
  • [that answer](http://stackoverflow.com/questions/23098047/change-default-value-for-table-column-with-rails-migrations-rails-4/27266641#27266641) refers changing the default value of a column. my answer sets whether this column allow null value or not. – ran632 Nov 23 '15 at 08:42
  • 1
    @TobiasLiefke because this answer is the only correct answer, even 7 years later. It solves the problem, removing NOT NULL constraint, which has nothing to do with column defaults – Ryan Romanchuk Jan 10 '22 at 21:29
  • @RyanRomanchuk I added my comment when there was no text at all. If I remove it now, ran632s comment would make less sense. And the answer still lacks the information, which you just have given. See the answers from ddebruler and Rick Smith for an example: Always explain, why this code solves the problem. – Tobias Liefke Jan 12 '22 at 07:17
16

It sounds like you're not trying to change the default value of the column, but rather to remove the NOT NULL constraint and allow null values (i.e. change from "null: false" to the default "null: true"). If that's the case, then you can use change_column_null:

class ChangeNameNull < ActiveRecord::Migration
  def change
    change_column_null :people, :name, true
  end
end

Edit 1:- Fixed typo

Gaurav Singh
  • 12,707
  • 5
  • 22
  • 24
ddebruler
  • 161
  • 1
  • 3
3
def change
  change_column_null(:users, :admin, false, <put a default value here> )
  # change_column(:users, :admin, :string, :default => "")
end

Changing a column with NULL values in it to not allow NULL will cause problems. This is exactly the type of code that will work fine in your development setup and then crash when you try to deploy it to your LIVE production. You should first change NULL values to something valid and then disallow NULLs. The 4th value in change_column_null does exactly that. See documentation for more details.

Also, I generally prefer to set a default value for the field so I won't need to specify the field's value every time I create a new object. I included the commented out code to do that as well.

Rick Smith
  • 9,031
  • 15
  • 81
  • 85