Escribí un módulo simple Cacheable que hace que sea simple para almacenar en caché los campos agregados en un modelo principal. El módulo requiere que el objeto principal implemente el método cacheable
y un método calc_
para cada campo que requiera el almacenamiento en caché en el nivel primario.¿Cómo uso la metaprogramación de Ruby para agregar devoluciones de llamada a un modelo de Rails?
module Cacheable
def cache!(fields, *objects)
objects.each do |object|
if object.cacheable?
calc(fields, objects)
save!(objects)
end
end
end
def calc(fields, objects)
fields.each { |field| objects.each(&:"calc_#{field}") }
end
def save!(objects)
objects.each(&:save!)
end
end
Me gustaría agregar devoluciones de llamada al modelo ActiveRecord en el que se incluye este módulo. Este método requeriría que el modelo implemente un hash de modelos principales y nombres de campo que requieran el almacenamiento en caché.
def cachebacks(klass, parents)
[:after_save, :after_destroy].each do |callback|
self.send(callback, proc { cache!(CACHEABLE[klass], self.send(parents)) })
end
end
Este enfoque funciona muy bien si agrego manualmente usando dos devoluciones de llamada tales como:
after_save proc { cache!(CACHEABLE[Quote], *quotes.all) }
after_destroy proc { cache!(CACHEABLE[Quote], *quotes.all) }
Pero, estoy recibiendo el siguiente error al intentar utilizar el método cachebacks
añadir éstos a las devoluciones de llamada .
cachebacks(Quote, "*quotes.all")
NoMethodError: undefined method `cachebacks' for #<Class:0x007fe7be3f2ae8>
¿Cómo agrego estas devoluciones de llamada dinámicamente a la clase?
Disculpa, no pude entender la última parte. ¿'Cita' es un modelo relacionado? ¿Podría publicar cómo se ve su clase en este momento? –
La respuesta que encontré basada en tu consejo debe explicar las cosas. También estoy interesado en el enfoque ActiveSupport :: Concern. – barelyknown