Как определить, была ли запись только создана или обновлена ​​в after_save - PullRequest
87 голосов
/ 12 февраля 2011

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

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

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

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

Ответы [ 5 ]

153 голосов
/ 25 августа 2011

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

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

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

30 голосов
/ 12 февраля 2011

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

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

def before_save
  @was_a_new_record = new_record?
  return true
end

def after_save
  if @was_a_new_record
    ...
  end
end
24 голосов
/ 05 февраля 2013

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

if created_at == updated_at
  # it's a newly created record
end
23 голосов
/ 29 ноября 2012

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

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

Подробнее здесь: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

16 голосов
/ 15 сентября 2013

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

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

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

...