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?

【勉強会参加】Once/campのコードリーディング会 Railsマイグレーションでexecuteを使う時のロールバック対応

Posted at

Railsマイグレーションでexecuteを使う時のロールバック対応

はじめに

Rails勉強会に参加しました。
今回は、「Once/camp」のコードを読みながら、Railsマイグレーションでexecuteを使う時のロールバック対応について学習をしました。
正直勉強会の内容は全くわかりませんでしたが、大変勉強になりました。

executeを使う際は、ロールバックができないようです

Railsのマイグレーションで生SQLを実行する際、executeメソッドを使用しますが、そのままではロールバックができません。本記事では、ロールバック可能なexecuteの書き方について備忘録としてまとめます。

executeメソッドの基本

マイグレーションファイルで生SQLを実行したい場合、executeメソッドを使用

class CreateMessageSearchIndex < ActiveRecord::Migration[8.0]
  def change
    execute <<~SQL
      CREATE VIRTUAL TABLE message_search_index 
      USING FTS5(content, content=messages)
    SQL
  end
end

しかし、この書き方ではロールバックができない

ロールバック可能にする方法

方法1: up / down を明示的に分ける

changeメソッドの代わりに、updownメソッドを定義

class CreateMessageSearchIndex < ActiveRecord::Migration[8.0]
  def up
    execute <<~SQL
      CREATE VIRTUAL TABLE message_search_index 
      USING FTS5(content, content=messages)
    SQL
  end

  def down
    execute <<~SQL
      DROP TABLE message_search_index
    SQL
  end
end

この方法

  • rails db:migrateを実行するとupが実行される
  • rails db:rollbackを実行するとdownが実行される

方法2: reversible ブロックを使う

changeメソッドの中でreversibleブロックを使用する方法もある

class CreateMessageSearchIndex < ActiveRecord::Migration[8.0]
  def change
    reversible do |dir|
      dir.up do
        execute <<~SQL
          CREATE VIRTUAL TABLE message_search_index 
          USING FTS5(content, content=messages)
        SQL
      end
      
      dir.down do
        execute <<~SQL
          DROP TABLE message_search_index
        SQL
      end
    end
  end
end

この方法は

  • changeメソッドの中でアップとダウンの両方を定義できる
  • より明示的に処理をまとめて書ける

実務での使い分け

up / down を使うケース

  • シンプルなSQL実行
  • マイグレーション全体がSQL直接実行のみの場合

reversible を使うケース

  • changeメソッド内で通常のマイグレーション処理とSQL実行を混在させたい場合
  • 複数のreversibleブロックをまとめたい場合
def change
  create_table :users do |t|
    t.string :name
    t.timestamps
  end

  reversible do |dir|
    dir.up do
      execute "CREATE INDEX ..."
    end
    
    dir.down do
      execute "DROP INDEX ..."
    end
  end
end

まとめ

  • executeをそのまま使うとロールバックできない
  • ロールバック可能にするにはup/downreversibleを使う
  • 実装の内容や好みに応じて使い分ける

特にSQLiteのFTS5など、Railsのマイグレーションメソッドで表現できない機能を使う場合は、必ずロールバック方法も考慮


初学者のため、間違えていたらすいません。

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?