web-dev-qa-db-ja.com

レコードがafter_saveで作成または更新されたかどうかを判断する方法

#new_record?関数は、レコードが保存されているかどうかを判断します。ただし、after_saveフックでは常にfalseです。レコードが新しく作成されたレコードか、更新された古いレコードかを判断する方法はありますか?

before_createなどの別のコールバックを使用してモデルにフラグを設定したり、dbに別のクエリを要求したりしないことを望んでいます。

どんなアドバイスも大歓迎です。

編集:after_saveフックでそれを決定する必要があり、私の特定のユースケースでは、updated_atまたはupdated_onタイムスタンプはありません

89
Aaron Qian

after_saveコールバックにこれを使用したいと考えていました。

より簡単な解決策は、id_changed?updateで変更されないため)またはタイムスタンプ列が存在する場合はcreated_at_changed?を使用することです。

更新:@mitsyが指摘しているように、コールバック以外でこのチェックが必要な場合は、id_previously_changed?を使用します。 docs を参照してください。

156
Zubin

いいえRailsここで私が知っている魔法、あなたは自分でそれをしなければなりません。仮想属性を使用してこれをきれいにすることができます...

モデルクラスで:

def before_save
  @was_a_new_record = new_record?
  return true
end

def after_save
  if @was_a_new_record
    ...
  end
end
30
Jeff Paquette

doupdated_atタイムスタンプを持つ人のための、さらに別のオプション:

if created_at == updated_at
  # it's a newly created record
end
24
colllin

after_createコールバックがあります。このコールバックは、レコードが新しいレコードである場合にのみ保存されます。これが変更および保存された既存のレコードである場合に使用するafter_updateコールバックもあります。 after_saveまたはafter_createが呼び出された後、両方の場合にafter_updateコールバックが呼び出されます。

新しいレコードが保存された後に何かを行う必要がある場合は、after_createを使用します。

詳細はこちら: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

23
sharpone

オブジェクトはすでに保存されているため、以前の変更を確認する必要があります。 IDは、作成後にのみ変更する必要があります。

# true if this is a new record
@object.previous_changes[:id].any?

インスタンス変数@new_record_before_saveもあります。次の方法でアクセスできます。

# true if this is a new record
@object.instance_variable_get(:@new_record_before_save)

どちらもかなりいですが、オブジェクトが新しく作成されたかどうかを知ることができます。お役に立てば幸いです!

16
Tom Rossi