4

Devise と paranoia(acts_as_paranoid) gem には複雑な問題があります。私の User モデルは比較的単純です。

class User < AR::Base
  devise :confirmable, :other_config_options
  acts_as_paranoid
end

確認可能なオプションなしで、最初に Devise gem を追加しました。その後、この移行で確認可能なオプションを後で追加しました。

def up
  add_column :users, :confirmed_at, :datetime
  add_column :users, :confirmation_token, :string
  add_column :users, :confirmation_sent_at, :datetime
  add_column :users, :unconfirmed_email, :string

  add_index :users, :confirmation_token, unique: true

  User.update_all(:confirmed_at => Time.now)
end

ここまでは問題ありません。次に、Paranoia gem とacts_as_paranoidラインを User モデルに追加しました。データベースは現在の状態で問題ありませんが、データベースをリセットして本番データと同期しようとしていますが、ここで問題が発生しています。db:reset を実行すると、上記の移行に失敗します。

PG::UndefinedColumn: ERROR:  column users.deleted_at does not exist

acts_as_paranoid問題は、現在のデータベース スナップショットでのみ有効なディレクティブがモデルに含まれていることです。User::deleted_at存在しない以前のデータベース スナップショットにロールバックすると、paranoia gem は削除されていないオブジェクトのみを更新しようとし、クエリは失敗します。

この状況を処理するエレガントな方法について何か考えはありますか?

4

3 に答える 3

4

これが最もエレガントな解決策かどうかは完全にはわかりませんが、古い移行をUser.with_deleted.update_all(:confirmed_at => Time.now)(まあ、私のモデルのバージョン)で更新することで解決しました。

Deleted_at を設定したユーザーに Confirmed_at を設定しないようにするには、機能しない可能性があります。私にとっては、削除されたユーザーにこのフィールドが設定されているかどうかはあまり気にしませんでした (私にとっては、これは開発/テストの問題であり、通常は最初にレコードがない場合に発生します)。

結局のところ、DML 移行にシードまたは gem を使用することを検討する時が来たのではないかと思います。

于 2015-06-08T21:29:45.860 に答える
3

unscopedモデル + 移行 + act_as_paranoid の使用中に使用します。

すべてのユーザーを更新する行は次のようになります。

User.unscoped.update_all(:confirmed_at => Time.now)

于 2017-07-19T13:00:48.267 に答える
0

allおよびeachループを実行していた既存の移行でエラーが発生していました

したがって、コードを次のように更新しました。

Object.all.each do |obj|

に:

Object.with_deleted.each do |obj|

そして、それwith_deleted.eachは問題を解決しました

お役に立てれば!

于 2018-12-04T14:15:48.110 に答える