¿El #new_record? La función determina si se ha guardado un registro. Pero siempre es falso en el after_save
gancho. ¿Hay alguna forma de determinar si el registro es un registro recién creado o uno antiguo de actualización?
Espero no usar otra devolución de llamada, como before_create
establecer una bandera en el modelo o requerir otra consulta en la base de datos.
Se agradece cualquier consejo.
Editar: Necesito determinarlo en el after_save
gancho, y para mi caso de uso particular, no hay una marca de tiempo updated_at
oupdated_on
ruby-on-rails
activerecord
activemodel
Aaron Qian
fuente
fuente
Respuestas:
Estaba buscando usar esto para una
after_save
devolución de llamada.Una solución más sencilla es usar
id_changed?
(ya que no cambiaráupdate
) o inclusocreated_at_changed?
si hay columnas de marca de tiempo.Actualización: como señala @mitsy, si esta verificación es necesaria fuera de las devoluciones de llamada, use
id_previously_changed?
. Ver documentos .fuente
after_save
.id_changed?
será falso después de que se guarde el registro (al menos fuera de los ganchos). En ese caso, puede utilizarid_previously_changed?
No hay magia de rieles aquí que yo sepa, tendrás que hacerlo tú mismo. Podrías limpiar esto usando un atributo virtual ...
En tu clase de modelo:
fuente
Sin embargo, otra opción, para aquellos que hacen tiene una
updated_at
marca de tiempo:fuente
created_at
igualarupdated_at
en unaafter_save
devolución de llamada en cualquier momento que no sea cuando se creó por primera vez?"created_at
yupdated_at
será igual en unaafter_save
devolución de llamada. En todas las demás situaciones, no serán iguales en laafter_save
devolución de llamada.Hay una
after_create
devolución de llamada a la que solo se llama si el registro es un registro nuevo, después de guardarlo . También hay unaafter_update
devolución de llamada para usar si se trataba de un registro existente que se cambió y se guardó. Laafter_save
devolución de llamada se llama en ambos casos, después de que se llameafter_create
oafter_update
.Úselo
after_create
si necesita que algo suceda una vez después de que se haya guardado un nuevo registro.Más información aquí: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
fuente
Dado que el objeto ya se ha guardado, debería consultar los cambios anteriores. La ID solo debe cambiar después de crear.
También hay una variable de instancia
@new_record_before_save
. Puede acceder a eso haciendo lo siguiente:Ambos son bastante feos, pero te permitirían saber si el objeto se ha creado recientemente. ¡Espero que ayude!
fuente
after_save
devolución de llamada usando Rails 4 y ninguno de estos está funcionando para identificar este nuevo registro.@object.previous_changes[:id].any?
es bastante simple y elegante. Me funciona después de que se actualiza el registro (no lo llamo desdeafter_save
).@object.id_previously_changed?
es un poco menos feo.after_save
Rails 4 que le gustaría ver enchanges[:id]
lugar deprevious_changes[:id]
. Sin embargo, esto está cambiando en Rails5.1 (ver discusión en github.com/rails/rails/pull/25337 )previous_changes.key?(:id)
para una mejor comprensión.Rails 5.1+ forma:
fuente
Para Rails 4 (verificado en 4.2.11.1), los resultados de
changes
y losprevious_changes
métodos son hashes vacíos{}
en la creación de objetos dentroafter_save
. Entonces,attribute_changed?
métodos comoid_changed?
no funcionarán como se esperaba.Pero puede aprovechar este conocimiento y, sabiendo que al menos 1 atributo debe estar en la
changes
actualización, verifique sichanges
está vacío. Una vez que confirme que está vacío, debe estarlo durante la creación del objeto:fuente
Me gusta ser específico, incluso yo sé que
:id
no debería cambiar en la normalidad, peroSiempre es más barato ser específico en lugar de encontrar un error inesperado muy extraño.
De la misma manera si espero una
true
bandera de un argumento no confiableEsto ahorra muchas horas para no estar sentado sobre errores extraños.
fuente