1. ホーム
  2. ruby-on-rails

[解決済み] Railsマイグレーションで、あるカラムを別のカラムの値に更新する

2023-07-05 03:46:12

質問

Railsアプリで数十万件のレコードがあるテーブルがあるのですが、そのテーブルには created_at のタイムスタンプしかありません。これらのレコードを編集する機能を追加しているので、そのために updated_at のタイムスタンプをテーブルに追加したいと思います。このカラムを追加するためのマイグレーションでは、すべての行を更新して、新しい updated_at が古い created_at にマッチします。Railsで新しく作成された行は、これがデフォルトだからです。を行うことができました。 find(:all) を実行してレコードを繰り返し処理することもできますが、テーブルのサイズが大きいので何時間もかかってしまいます。私が本当にやりたいことは

UPDATE table_name SET updated_at = created_at;

Railsのマイグレーションで、生のSQLを実行するのではなく、ActiveRecordを使用してそれを行うより良い方法はありますか?

どのように解決するのですか?

マイグレーションを作成する

rails g migration set_updated_at_values

で、その中に次のようなことを書きます。

class SetUpdatedAt < ActiveRecord::Migration
  def self.up
    Yourmodel.update_all("updated_at=created_at")
  end

  def self.down
  end
end

この方法では、次の2つのことが実現できます。

  • これは反復可能なプロセスであり、可能なデプロイメント (必要な場所) ごとに実行されます。
  • これは効率的です。これ以上ruby的なソリューション(効率的である)は思いつきません。

注:activerecordを使ってクエリを書くのが大変な場合、マイグレーション内でraw sqlを実行することもできます。次のように書けばよいのです。

Yourmodel.connection.execute("update your_models set ... <complicated query> ...")