Как определить, была ли запись только что создана или обновлена ​​в after_save

#new_record? функция определяет, была ли сохранена запись. Но это всегда неверно в hook after_save. Есть ли способ определить, является ли запись новой созданной записью или старой из обновления?

Я надеюсь не использовать другой обратный вызов, например before_create, чтобы установить флаг в модели или потребовать другой запрос в db.

Любые советы приветствуются.

Изменить: нужно определить его в after_save, а для моего конкретного варианта использования нет updated_at или updated_on timestamp

Ответ 1

Я хотел использовать это для обратного вызова after_save.

Более простым решением является использование id_changed? (поскольку оно не изменится на update) или даже created_at_changed?, если присутствуют столбцы временной метки.

Обновление. Как указывает @mitsy, если эта проверка необходима вне обратных вызовов, используйте id_previously_changed?. См. docs.

Ответ 2

Никаких рельсов здесь, о которых я знаю, вам придется сделать это сами. Вы можете очистить его с помощью виртуального атрибута...

В вашем классе модели:

def before_save
  @was_a_new_record = new_record?
  return true
end

def after_save
  if @was_a_new_record
    ...
  end
end

Ответ 3

Еще один вариант для тех, у кого есть метка updated_at:

if created_at == updated_at
  # it a newly created record
end

Ответ 4

Существует обратный вызов after_create, который вызывается только в том случае, если запись является новой записью после ее сохранения. Существует также обратный вызов after_update для использования, если это была существующая запись, которая была изменена и сохранена. Обратный вызов after_save вызывается в обоих случаях после вызова after_create или after_update.

Используйте after_create, если вам нужно, чтобы что-то произошло один раз после сохранения новой записи.

Дополнительная информация здесь: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

Ответ 5

Поскольку объект уже сохранен, вам нужно посмотреть предыдущие изменения. Идентификатор должен изменяться только после создания.

# 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)

Оба довольно уродливые, но они позволят вам узнать, был ли объект вновь создан. Надеюсь, что это поможет!