14

場合によっては、データの移行が必要になります。時間が経過すると、ドメイン モデルを使用したコードの変更と移行は無効になり、移行は失敗します。データ移行のベスト プラクティスは何ですか?

問題を明確にするために例を作ってみました:

このことを考慮。移行があります

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
  def up
    User.all.each do |user|
      user.applied_at = user.partner_application_at
      user.save
   end
 end

もちろん、これは完全に正常に動作します。後で、スキーマの変更が必要になります

class AddAcceptanceConfirmedAt < ActiveRecord::Migration
  def change
    add_column :users, :acceptance_confirmed_at, :datetime
  end
end

class User < ActiveRecord::Base
  before_save :do_something_with_acceptance_confirmed_at
end

あなたにとっては、問題ありません。それは完全に実行されます。しかし、最初の移行をまだ実行していない同僚が今日これらの両方をプルした場合、最初の移行の実行時に次のエラーが発生します。

rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `acceptance_confirmed_at=' for #<User:0x007f85902346d8>

それはチーム プレーヤーではありません。彼はあなたが導入したバグを修正します。あなたは何をすべきでしたか?

4

3 に答える 3

14

これは、Using Models in Your Migrations

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
  class User < ActiveRecord::Base
  end

  def up
    User.all.each do |user|
      user.applied_at = user.partner_application_at
      user.save
   end
 end

ミーシャのコメントの後に編集

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
  class User < ActiveRecord::Base
  end

  def up
    User.update_all('applied_at = partner_application_at')
  end
 end
于 2012-10-24T08:33:21.110 に答える
13

ベスト プラクティスは、移行でモデルを使用しないことです。移行は AR マップの方法を変更するため、まったく使用しないでください。すべてSQLで行います。この方法では、常に機能します。

これ:

User.all.each do |user|
  user.applied_at = user.partner_application_at
  user.save
end

私はこのようにします

update "UPDATE users SET applied_at=partner_application_at"
于 2012-10-24T08:33:27.633 に答える
0

前述のように、スキーマ移行の一部として「データの移行」を実行できない場合がありました。「データの移行」は、「履歴データの不一致を修正する」または「Solr/Elasticsearch インデックスを更新する」ことを意味する場合があるため、複雑な作業になります。この種のタスクについては、この宝石をチェックしてください https://github.com/OffgridElectric/rails-data-migrations

この gem は、Rails スキーマの移行をデータ移行から切り離すように設計されているため、デプロイ時にダウンタイムが発生せず、全体的な管理が容易になります。

于 2016-11-07T12:20:53.253 に答える