Can I rollback using change_column method in Rails 4 and above?
Asked Answered
B

4

8

Is change_column method able to rollback when it is used in migrations in Rails 4 and above?

Here is an example:

def change
  change_column etc
end

Should I use up and down methods instead?

Bretbretagne answered 21/10, 2016 at 15:35 Comment(1)
No, you should just use up and down. Clean and clearer, especially for those who have been with Rails since version 2 and 3.Psychedelic
Q
18

change_column cannot be reverted by default. Rails cannot know the column definition before the migration, so it cannot roll back to this original definition.

Therefor starting with Rails 4, you can provide Rails with the necessary information. That's what the reversible method is for:

def change
  reversible do |dir|
    dir.up do
      change_column :users, :score, :decimal, precision: 6, scale: 2
    end
    dir.down do
      change_column :users, :score, :decimal, precision: 4, scale: 2
    end
  end
end

At first glance, this seems more complicated than using up and down. The advantage is, that you can mix it with reversible migrations.
If i.e. you add a bunch of fields to a table and have to change few fields along, you can use change_table and add_column together with reversible to have a clean and compact migration:

def change
  change_table :users do |t|
    t.string :address
    t.date :birthday
    # ...
  end

  reversible do |dir|
    dir.up do
      change_column :users, :score, :decimal, precision: 6, scale: 2
    end
    dir.down do
      change_column :users, :score, :decimal, precision: 4, scale: 2
    end
  end
end
Quita answered 5/2, 2017 at 10:53 Comment(3)
Thanks, I tried to do a rollback with change_column and rails say that: This migration uses change_column, which is not automatically reversible.Bretbretagne
Is the answer to original question NO?Donnell
literally the answer to the original question should I use up an down methods instead? is YES ... and there are more options.Quita
G
1

It's possible rollback a migration with change_columns in rails 4 or rails 5 with:

def change end

Yes, it is possible to rollback a migration with empty (as well as correct non-empty) change method.

When you actually have something there, you might not be able to revert a migration with for example, a remove_column if you did not specify the type of the column you removed.

Also, if for example you have a change_column in change method. How should Rails know, which type/name/whatever the column had before the change if not from down method? :)

So if you are planning on rolling back and forth, you would want to be as explicit, as possible, so using up and down is a very good (best, actually) idea.

Griner answered 21/10, 2016 at 15:37 Comment(4)
I did not express myself well, I've updated the questionBretbretagne
@MatheusSilva, maybe you didn't, but I think i did :) I recommended using up/down + provided an example of why just change is not perfectGriner
Thanks. I seen that the new versions of Rails can revert when the change is remove or rename, but I did not find about change_column.Bretbretagne
@MatheusSilva older versions could revert remove (which I used in my example), but only if you specify the column type. Try reverting the remove_column without a type specified, from what i remember, you won't be able to do that. Besides, having up and down is more explicit for people, who sees the migration first time, so my vote is for using up/down predominantlyGriner
P
0

You can also use

change_column_null(table_name, column_name, null, default = nil)

To save some code. Activerecord knows how to rollback this one.

Poleaxe answered 8/10, 2018 at 15:50 Comment(0)
L
-2

EDIT: I just want to apologize for taking so long to update this answer, I originally didn’t understand the question.

When you are writing a migration in Rails you have two approaches you can take you can use change or the up down approach. When you use change it is important to be aware of what your migration is doing, because the change construct will attempt to infer what the opposite action would be in the event you have to rollback the migration. Migration methods like add_column, add_index, create_table, etc, have opposite actions rails can infer. A migration like change_column however can be literally anything so like Martin said you would need to include the reversible block for rails to know what to do when the revert could be ambiguous.

Langford answered 21/10, 2016 at 15:37 Comment(2)
Not really, if I try do a rollback with change_column rails alerts: This migration uses change_column, which is not automatically reversible.Bretbretagne
Yes it depends on what is being done in the change statement, like adding a column has an reversible action witch rails understands, where as other actions may not.Langford

© 2022 - 2024 — McMap. All rights reserved.