validates rails example before_update before association after_create after active ruby ruby-on-rails-3 activerecord callback

ruby - rails - rieles 3: ¿Debo dar una respuesta verdadera en una devolución de llamada before_save para que un object.save funcione?



rails before_update (4)

Class User before_save :set_searchable def set_searchable self.searchable = true if self.status == :active end end >> u = User.last >> u.save false

u.save siempre devuelve falso. Si elimino la función before_save, también funciona si doy una respuesta verdadera en la función before_save, funciona

¿Entonces necesito dar declaraciones de devolución en before_save? ¿ActiveRecord guarda un objeto si el before_save devuelve falso?

¿Dónde puedo ver una documentación completa sobre las devoluciones de llamada y su flujo de trabajo?

Gracias por adelantado


De: http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

Si una devolución de llamada before_ * devuelve falso, se cancelan todas las devoluciones de llamada posteriores y la acción asociada. Si una devolución de llamada after_ * devuelve falso, se cancelan todas las devoluciones de llamada posteriores. Las devoluciones de llamada generalmente se ejecutan en el orden en que se definen, con la excepción de las devoluciones de llamada definidas como métodos en el modelo, que se llaman los últimos.

Entonces sí.


La documentación dice

Si una devolución de llamada before_ * devuelve falso, se cancelan todas las devoluciones de llamada posteriores y la acción asociada. Si una devolución de llamada after_ * devuelve falso, se cancelan todas las devoluciones de llamada posteriores. Las devoluciones de llamada generalmente se ejecutan en el orden en que se definen, con la excepción de las devoluciones de llamada definidas como métodos en el modelo, que se llaman los últimos.

PERO

es posible que desee revisar esto (lo he probado yo mismo y el problema es 100% auténtico)

Además, también hay un error relacionado con before_save que quizás quieras saber. Consulta el comentario here

Como se dice en el comentario se observa a veces.

Hagas lo que hagas, ten en cuenta que hay algunos problemas con la devolución de llamada de Rails. Esto te ahorraría tiempo cuando te encontraras con uno de esos


No, no es necesario que devuelva true desde las devoluciones de llamada de Rails. No puede devolver nada en absoluto, o verdadero, o 3.141592, y aún se guardará. Lo único que importa es si devuelve falso, y esto solo se aplica antes de Rails 5. Devolver falso cancelaría el ahorro antes de Rails 5. Devolver true nunca tuvo ningún efecto.

Para Rails 5+, la nueva forma de bloquear la actualización es lanzar una excepción: throw(:abort) . . Esto es más intuitivo y menos propenso a errores. El valor de retorno no tiene ningún efecto sobre si se guardará, a menos que configure el comportamiento heredado.

Es válido, y es una buena práctica de SECAR, simplemente continuar con su negocio y no devolver nada en absoluto; solo asegúrese de evitar devolver falsos accidentalmente de forma implícita si utiliza Rails anteriores. Por ejemplo:

# This is fine, record will be saved def before_save self.foo = ''bar'' # Implicitly returns ''bar'' end # This is an accidental veto, record will not be saved def before_save Rails.logger.info ''user requested save'' self.fresh = false # Oops! Implicitly returns false end # One way to rectify the above example (another would be to re-order if it''s possible) def before_save Rails.logger.info ''user requested save'' self.fresh = false return # Implicitly returns nil. Could also do `return true` end

Lo que se tiene aquí es que puede olvidar que algunas funciones de tipo "de procedimiento" devolverán un booleano como una clase de código de estado o simplemente porque la implementación termina con un booleano como efecto secundario. Podría pensar que está mutando una cadena o algo así, pero termina vetando accidentalmente la devolución de llamada. Entonces, aunque creo que generalmente es demasiado ruidoso para regresar explícitamente de las devoluciones de llamada, sí es necesario tener cuidado con las devoluciones implícitas. Una de las razones por las que la gente defendía que se hiciera realidad era protegerse contra este problema.


Otra forma más limpia de establecer columnas booleanas sin return es usar tap

def set_searchable self.tap{|u| u.searchable = status.eql?(:active) } end