0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

マイグレーション【Railsガイド v7.0を読む】

Posted at

なんとなく使っているので、ちゃんと理解を深めようということでRailsガイドを読んでまとめてみようと思います。

マイグレーションとは

Railsガイドより引用

マイグレーションは、データベーススキーマの継続的な変更(英語)を、統一的かつ簡単に行なうための便利な手法です。マイグレーションではRubyのDSLが使われているので、生のSQLを作成する必要がなく、スキーマおよびスキーマ変更がデータベースに依存しなくなります。

個別のマイグレーションは、データベースの新しい「バージョン」とみなせます。スキーマは空の状態から始まり、マイグレーションによる変更が加わるたびにテーブル、カラム、エントリが追加または削除されます。Active Recordはマイグレーションの時系列に沿ってスキーマを更新する方法を知っているので、履歴のどの時点からでも最新バージョンのスキーマに更新できます。Active Recordはdb/schema.rbファイルを更新し、データベースの最新の構造と一致するようにします。

マイグレーションファイル

マイグレーションファイルは、db/migrateフォルダ内にある。
ファイル名は、YYYYMMDDHHMMSS_create_tasks.rbのような形式。

前半部分YYYYMMDDHHMMSSは、マイグレーションを識別するUTCタイムスタンプ
後半部分create_tasksは、マイグレーション名

ファイルの後半部分(snake_case)create_tasksは、マイグレーションのクラス名(CamelCase)CreateTasksと一致する必要がある。

YYYYMMDDHHMMSS_create_tasks.rb
class CreateTasks < ActiveRecord::Migration[7.0]
end

作成

マイグレーションファイルは、以下のコマンド実行時にdb/migrateフォルダに作成される。

モデルを作成したとき

rails generate model モデル名

モデルを作成した時には、YYYYMMDDHHMMSS_create_モデル名s.rbが作成される。

個別にマイグレーションファイルを作成したとき

rails generate migration マイグレーションのクラス名

個別にマイグレーションファイルを作成したときは、YYYYMMDDHHMMSS_マイグレーションのクラス名(snake_case).rbが作成される。

編集

change

def change
# 変更を記述
end

changeメソッドを使用すると、ActiveRecordがマイグレーションをロールバックする方法を自動的に認識してくれる。
change_columnなど不可逆的なものもあるので、注意すること。

change_column :products, :part_number, :text

上記の例ではpart_numberをtext型に変更しているが、この記述からは変更前の型が分からないのでロールバックできない。( = 不可逆的)

changeメソッドでサポートされている可逆的なメソッドはRailsガイドv7.0 3.9 changeメソッドを使う
を参照。

不可逆的なメソッドを使用する場合は、reversibleメソッドを使用するか、up/downメソッドを使用し、明示的に通常通りに実行される処理とロールバックするときに実行する処理を指定する必要がある。

reversible

reversibleを使用すると、changeメソッド内で不可逆的な処理を記述する際に、通常通りマイグレーションする場合とロールバックする場合の処理を分けることができる。

class ExampleMigration < ActiveRecord::Migration[7.0]
  def change
    create_table :distributors do |t|
      t.string :zipcode
    end

    reversible do |dir|
      dir.up do
        # CHECK制約を追加
        execute <<-SQL
          ALTER TABLE distributors
            ADD CONSTRAINT zipchk
              CHECK (char_length(zipcode) = 5) NO INHERIT;
        SQL
      end
      dir.down do
        execute <<-SQL
          ALTER TABLE distributors
            DROP CONSTRAINT zipchk
        SQL
      end
    end

    add_column :users, :home_page_url, :string
    rename_column :users, :email, :email_address
  end
end

このマイグレーションをロールバックした場合、downブロックはカラムの削除とテーブルの削除の間に実行される。

up/down

def up
# 通常の変更を記述
end
def down
# upメソッドで行った変更をロールバックする処理を記述
end

upにはスキーマに対する変更方法を、downにはupメソッドによって行われた変更をロールバックする方法を記述する。

class ExampleMigration < ActiveRecord::Migration [7.0]
  def up
    create_table :distributors do |t|
      t.string :zipcode
    end

    # CHECK制約を追加
    execute <<-SQL
      ALTER TABLE distributors
        ADD CONSTRAINT zipchk
        CHECK (char_length(zipcode) = 5);
    SQL

    add_column :users, :home_page_url, :string
    rename_column :users, :email, :email_address
  end

  def down
    rename_column :users, :email_address, :email
    remove_column :users, :home_page_url

    execute <<-SQL
      ALTER TABLE distributors
        DROP CONSTRAINT zipchk
    SQL

    drop_table :distributors
  end
end

upメソッドでは、

  • テーブルの作成
  • CHECK制約を追加
  • カラムを追加
  • カラム名を変更

downメソッドでは、

  • カラム名を変更
  • カラムを削除
  • CHECK制約を削除
  • テーブルの削除

が行われる。(reversibleに記載のマーグレーションと同等の内容)

downメソッド内の処理の順序は、upメソッド内の処理順と真逆にする。

その他のメソッド

その他add_column, create_tableなどのメソッドは書き出すと長くなりそうなので以下を参照。
ActiveRecord::ConnectionAdapters::SchemaStatements Methods

実行

以下のコマンドでマイグレーションを実行できる

rails db:migrate

未実行のマイグレーションファイルが複数存在する場合は、ファイル名のタイムスタンプが古い順に実行される。

特定のバージョンまでマイグレーションを実行するには以下のようにバージョンを指定する。

rails db:migrate VERSION=YYYYMMDDHHMMSS

指定したバージョンが現在のバージョンより大きい場合、指定バージョンに到達するまでchangeメソッド、upメソッドが実行される。
(指定バージョンのマイグレーションファイルも実行される

指定したバージョンが現在のバージョンより小さい場合、指定バージョンに到達するまでロールバックされる。
(指定バージョンのマイグレーションファイルは実行されない

db/schema.rb

db:migrateを実行するとdb:schema:dumpコマンドも同時に呼び出され、db/schema.rbの内容がデータベースの構造と一致するように更新される。

db/schema.rbにバージョンが含まれているので、version: 2023_02_28_130514を見ればどのマイグレーションファイルまで実行されているかが確認できる。

db/schema.rb
ActiveRecord::Schema[7.0].define(version: 2023_02_28_130514) do

ロールバック

マイグレーションファイルに誤りがあり訂正したい場合など、直前に行ったマイグレーションをロールバックするには以下のコマンドを実行する。

rails db:rollback

このコマンドによりchangeメソッドを逆転実行するか、downメソッドを実行する形で直前のマイグレーションにロールバックする。

2つ以上のマイグレーションをロールバックするには、STEPパラメータでロールバックする数を指定する。
以下のコマンドで最後に行った3つのマイグレーションをロールバックできる。

rails db:rollback STEP=3

データベースを設定する

rails db:setup

このコマンドにより、以下がまとめて実行される

  • データベースの作成db:create
  • スキーマの読み込みdb:schema:load
  • seedデータを用いたデータベースの初期化db:seed

データベースをリセットする

rails db:reset

データベースをdropして、再度設定する。(rails db:drop db:setupと同等)
このコマンドは現在のdb/schema.rbをそのまま使い回すので、マイグレーションファイルを編集していてもその内容は反映されない。
マイグレーションファイルの内容を反映させるには、次のコマンドを実行する。

rails db:migrate:reset

参考文献

Railsガイド v7.0 - Active Record マイグレーション

ActiveRecord::ConnectionAdapters::SchemaStatements

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?