LoginSignup
2
2

More than 5 years have passed since last update.

Migration の revert 機能の使い方

Last updated at Posted at 2017-09-23

便利機能を見つけたので紹介します。

次のような処理があったとします。

カラム追加
change_table :users do |t|
  t.string :name
end

それを revert ブロックで囲めば逆の処理が走ります。

カラム削除
revert do
  change_table :users do |t|
    t.string :name
  end
end

既存の migtation を丸ごと revert したい場合はそのクラスを指定するだけでよいようです。

既存のmigration定義をrevertする
revert CreateUsers

以下は確認用コードです。

require "active_record"
ActiveRecord::VERSION::STRING   # => "5.1.4"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")

class A < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.string :name
    end
  end

  run self
end

class B < ActiveRecord::Migration[5.1]
  def change
    # users を drop
    revert A

    # 逆の逆の逆の逆なので users を create
    revert do
      revert do
        revert do
          revert A
        end
      end
    end

    # 再び users を drop
    revert A

    # users を create
    ActiveRecord::Migration.run A # A.migrate(:up) でも実行できる

    # 「nameカラム追加」の逆なので「nameカラムを削除」
    revert do
      change_table :users do |t|
        # 本当は string 型だけど嘘を書いてもいい
        t.integer :name
      end
    end

    # users を drop
    revert do
      create_table :users
    end
  end

  run self
end
# >> -- create_table(:users)
# >>    -> 0.0018s
# >> -- drop_table(:users)
# >>    -> 0.0001s
# >> -- create_table(:users)
# >>    -> 0.0003s
# >> -- drop_table(:users)
# >>    -> 0.0001s
# >> -- create_table(:users)
# >>    -> 0.0002s
# >> -- remove_column(:users, :name, :integer, {})
# >>    -> 0.0046s
# >> -- drop_table(:users)
# >>    -> 0.0001s

drop や remove 系メソッドに変換しなくてもいいのが楽ですね。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2