Me gustaría crear una función de devolución de llamada en rieles que se ejecute después de guardar un modelo.
Tengo este modelo, Reclamo que tiene un atributo 'estado' el cual cambia dependiendo del estado del reclamo, posibles valores están pendientes, avalados, aprobados, rechazados
La base de datos tiene 'estado' con el valor predeterminado de 'pendiente'.
Me gustaría realizar ciertas tareas después de que el modelo se crea por primera vez o se actualiza de un estado a otro, según el estado desde el que cambia.
Mi idea es tener una función en el modelo:
after_save :check_state
def check_state
# if status changed from nil to pending (created)
do this
# if status changed from pending to approved
performthistask
end
Mi pregunta es ¿cómo verifico el valor anterior antes del cambio dentro del modelo?
fuente
dirty
llamadas funcionan enafter_save
(tanto en Rails 2.3 como 3.x). Lo he usado varias veces.after_commit
devoluciones de llamada introducidas en Rails 3.x. Ciertamente funcionaránafter_save
.after_save
es una devolución de llamada para un estado entreafter DML
ybefore_commit
. Puede terminar toda la transacciónafter_save
lanzando una excepción. Si desea hacer algo después de guardar sin afectar la operación actual, useafter_commit
:-)puedes usar esto
self.changed
devuelve una matriz de todas las columnas que cambiaron en este registro
también puedes usar
self.changes
que devuelve un hash de columnas que cambiaron y antes y después de los resultados como matrices
fuente
self.
en estos, solo puede decirchanged
ychanges
.self
en el modelo en sí, pero puede llamarlos en cualquier objeto conobject.changed
yobject.changes
. :)Te recomiendo que eches un vistazo a uno de los complementos de máquina de estado disponibles:
Cualquiera de los dos le permitirá configurar estados y transiciones entre estados. Una forma muy útil y sencilla de gestionar sus necesidades.
fuente
Para Rails 5.1+, debe usar el método de atributo de registro activo: Saved_change_to_attribute?
Entonces, su modelo se verá así, si desea llamar a algún método basado en el cambio en el valor del atributo:
class Claim < ApplicationRecord after_save :do_this, if: Proc.new { saved_change_to_status?(from: nil, to: 'pending') } after_save :do_that, if: Proc.new { saved_change_to_status?(from: 'pending', to: 'approved') } def do_this .. .. end def do_that .. .. end end
Y si no desea verificar el cambio de valor en la devolución de llamada, puede hacer lo siguiente:
class Claim < ApplicationRecord after_save: :do_this, if: saved_change_to_status? def do_this .. .. end end
fuente
He visto surgir la pregunta en muchos lugares, así que escribí un pequeño rubygem para hacer el código un poco más agradable (y evitar un millón de declaraciones if / else en todas partes): https://github.com/ronna-s / on_change . Espero que eso ayude.
fuente
Estará mucho mejor si utiliza una solución bien probada como la gema state_machine .
fuente