tutorial seguridad rails proyecto mundo modelos librosweb hola desde controlador cero ruby-on-rails events activerecord attributes

ruby on rails - seguridad - ¿Devolución de llamada para cambiar los atributos de ActiveRecord?



seguridad en ruby on rails (6)

La forma más fácil que encontré:

after_save :my_method, :if => Proc.new{ self.my_attribute_changed? } def my_method ... do stuff... end

Soy consciente de ActiveRecord :: Dirty y los métodos relacionados, pero no veo un medio por el cual pueda suscribirme a un evento de cambio de atributo. Algo como:

class Person < ActiveRecord::Base def attribute_changed(attribute_name, old_value, new_value) end #or attribute_changed do |attribute_name, old_value, new_value| end end

¿Hay un estándar de Rails o plugin para esto? Siento que debe estar allí en algún lugar y solo me lo estoy perdiendo.


La respuesta de cwninja debería hacer el truco, pero hay un poco más.

En primer lugar, el manejo de los atributos básicos se realiza con el método write_attribute, por lo que debería aprovechar esto.

Los rieles también tienen una estructura de devolución de llamada incorporada que podría ser agradable de utilizar, aunque no permite pasar argumentos, lo que es un poco molesto.

Usando devoluciones de llamada personalizadas, podrías hacerlo así:

class Person < ActiveRecord::Base def write_attribute(attr_name, value) attribute_changed(attr_name, read_attribute(attr_name), value) super end private def attribute_changed(attr, old_val, new_val) logger.info "Attribute Changed: #{attr} from #{old_val} to #{new_val}" end end

Si quisiera tratar de usar las devoluciones de llamada de Rails (especialmente útil si puede tener múltiples devoluciones de llamada y / o subclases) podría hacer algo como esto:

class Person < ActiveRecord::Base define_callbacks :attribute_changed attribute_changed :notify_of_attribute_change def write_attribute(attr_name, value) returning(super) do @last_changed_attr = attr_name run_callbacks(:attribute_changed) end end private def notify_of_attribute_change attr = @last_changed_attr old_val, new_val = send("#{attr}_change") logger.info "Attribute Changed: #{attr} from #{old_val} to #{new_val}" end end


Para rieles 3:

class MyModel < ActiveRecord::Base after_update :my_listener, :if => :my_attribute_changed? def my_listener puts "Attribute ''my_attribute'' has changed" end end

Comentado en: https://.com/a/1709956/316700

No encuentro documentación oficial sobre esto.


Para rieles 4

def attribute=(value) super(value) your_callback(self.attribute) end

Si desea sobrescribir el valor del atributo, debe usar write_attribute(:attribute, your_callback(self.attribute)) y no attribute= o lo superará hasta que obtenga una excepción de pila demasiado profunda.


Siempre se puede acceder al método privado changed_attributes y verificar las claves allí usando a before_save y hacer con él lo que quieras.


tratar:

def attribute_changed(attribute_name, old_value, new_value) end def attribute=(attribute_name, value) returning(super) do attribute_changed(attribute_name, attribute_was(attribute_name), attribute(attribute_name)) end end

Acabo de inventar esto ahora, pero debería funcionar.