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?

【Rails】reset_column_informationの役割と使用例

Posted at

はじめに

Railsのマイグレーションで新しいカラムを追加した直後に、そのカラムを使って既存データを更新したい場面があります。
その際に必要となるのがreset_column_informationです。本記事はその学習記録です。

reset_column_informationとは

reset_column_informationは、マイグレーション中にスキーマ変更を即座にモデルに反映させるためのメソッドです。
内部的にはテーブルのカラム情報キャッシュをクリアし、最新のスキーマを再読み込みして新しいキャッシュを生成します。

使用例

例えば、projectsテーブルにarchivedというフラグを追加し、1年以上前のプロジェクトを自動的にアーカイブしたいとします。
その場合のマイグレーションは以下のようになります。

class AddArchivedToProjects < ActiveRecord::Migration[7.2]
  def up
    # booleanカラムを追加
    add_column :projects, :archived, :boolean, default: false, null: false

    # モデルに最新のカラム情報を反映
    Project.reset_column_information

    # 既存データを一括で更新
    Project.where("created_at < ?", 1.year.ago).update_all(archived: true)
  end

  def down
    remove_column :projects, :archived
  end
end

この例のポイント

  • add_column直後はDBにはカラムが存在するが、Projectモデルはarchivedカラムをまだ認識していない
  • そのままupdate_all(archived: true)を実行すると、エラーや不整合が発生する可能性がある
  • reset_column_informationを呼ぶことで、モデルに最新のスキーマを再読み込みさせることができる

おわりに

スキーマを変更した直後に、そのカラムを使ってデータを更新する場合にはreset_column_informationが必須です。
一方で、単にカラムを追加するだけでデータ更新を行わない場合には不要です。

あわせて注意したい点は以下の通りです。

  • 更新時はシンプルなSQLを使う
    • update_allexecute "UPDATE ..." のようなメソッドを使う方が安全
    • update!などを使うとバリデーションやコールバックが発生し、コード変更の影響を受けやすい
  • 大規模データの更新はマイグレーションではなく、Rakeタスクなどで別途実行する
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?