Railsのchange とup & down の違い

railsのchangeとup&down Ruby
railsのchangeとup&down

Railsのマイグレーションファイルの記載方法として、

changeを使った方法と、up & downを使った方法があります。

それぞれの違いについては、他のネット記事でも紹介がありますが、
どういう場合に、どっちを使ったらいいねんというのを記載したいなと思います。

まずは、changeとup & down の記載方法について、おさらいがてら軽く記載します。

change での書き方

Userテーブルにstring型の存detailカラムを追加したいとき…

class AddDetailToUser < ActiveRecord::Migration
  def change
    add_column :users, :detail, :string
  end
end

up & down での書き方

changeの時と同様に、Userテーブルにstring型のdetailカラムを追加したいとき…

class AddDetailToUser < ActiveRecord::Migration
  def up
    add_column :users, :detail, :string
  end

  def down
    remove_column :users, :detail
  end
end

change と up & down の違い

カラムの追加について、up & down記法だと6行必要な一方で、change記法だと、たった3行で済みます。

それは、change記法であれば、railsがよしなにロールバック時の処理を推測してくれるからです。

changeの内容が、「add_column」かー。
カラム追加したいってことやから、ロールバック時はカラム削除してあげたら良さそうやな!

changeの方が、以下のコマンドで一発でファイル作成してくれるし、
なにかと便利なように思えます。

だがしかし、rails も神ではない。
全て推測できるわけじゃないんです。

例えば、detailカラムのデータ型をstring → textに変えたい場合、推測はできないのです。

class ChangeColumnDetail < ActiveRecord::Migration
  def change
    change_column :users, :detail, :text
  end
end

この記載で良いようにみえます、実際にマイグレーションも通ります。
ただ、bin/rails db:rollbackすると、怒られちゃいます。

rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

This migration uses change_column, which is not automatically reversible.
To make the migration reversible you can either:
1. Define #up and #down methods in place of the #change method.
2. Use the #reversible method to define reversible behavior.

rails 様の推測は、あくまでこのファイルだけを見て行われます。

なので…

changeの内容が、「change_column」かー。
あれ待って…そしたらロールバック時って、何に戻してあげたらいいん??beforeはなんなん??

change記法だと、どう変わるかのAfterの記載しかないので、
さすがのrails様でも、何に戻してあげたらよいかのBeforeは推測できず、怒ってしまうという訳です。

なので、rails様が推測できないような場合は、up & down 記法で書かないとダメなんですねー。

class ChangeColumnDetail < ActiveRecord::Migration
  def up
    change_column :users, :detail, :text
  end

  def down
    change_column :users, :detail, :string
  end
end

rails 様が推測できない場合というのは、カラム削除時も該当します。

changeの内容が「remove_column」かー。

あれちょっと待って、そしたらロールバック時って、カラムを追加したらいいの??
でもどんなカラムを追加したらいいの?? 指定してくれないとそこまではちょっと…。

rails 様が推測できるかできないかなんて、こちとらわからん。
そしたらもう全部、up & down で書いちゃえばいいやんとなりそうです。

タイトルとURLをコピーしました