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

dirtyllamadas funcionan enafter_save(tanto en Rails 2.3 como 3.x). Lo he usado varias veces.after_commitdevoluciones de llamada introducidas en Rails 3.x. Ciertamente funcionaránafter_save.after_savees una devolución de llamada para un estado entreafter DMLybefore_commit. Puede terminar toda la transacciónafter_savelanzando una excepción. Si desea hacer algo después de guardar sin afectar la operación actual, useafter_commit:-)puedes usar esto
self.changeddevuelve una matriz de todas las columnas que cambiaron en este registro
también puedes usar
self.changesque devuelve un hash de columnas que cambiaron y antes y después de los resultados como matrices
fuente
self.en estos, solo puede decirchangedychanges.selfen el modelo en sí, pero puede llamarlos en cualquier objeto conobject.changedyobject.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 endY 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 endfuente
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