Ho scritto un semplice modulo Cachebile che semplifica la cache dei campi aggregati in un modello principale. Il modulo richiede che l'oggetto padre implementa il metodo cacheable
e un metodo calc_
per ogni campo che richiede la memorizzazione nella cache a livello padre.Come utilizzare la metaprogrammazione di Ruby per aggiungere callback a un modello 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
Vorrei aggiungere i callback al modello ActiveRecord in cui è incluso questo modulo. Questo metodo richiede che il modello implementa un hash di modelli principali e nomi di campi che richiedono la memorizzazione nella cache.
def cachebacks(klass, parents)
[:after_save, :after_destroy].each do |callback|
self.send(callback, proc { cache!(CACHEABLE[klass], self.send(parents)) })
end
end
Questo approccio funziona grande se aggiungo manualmente sia utilizzando callback come ad esempio:
after_save proc { cache!(CACHEABLE[Quote], *quotes.all) }
after_destroy proc { cache!(CACHEABLE[Quote], *quotes.all) }
Ma, sto ricevendo il seguente errore quando si tenta di utilizzare il metodo cachebacks
per aggiungere questi per callback .
cachebacks(Quote, "*quotes.all")
NoMethodError: undefined method `cachebacks' for #<Class:0x007fe7be3f2ae8>
Come si aggiungono questi callback alla classe in modo dinamico?
Scusa, non ho potuto dare un senso all'ultima parte. 'Quote' è un modello correlato? Potresti per favore pubblicare come appare la tua classe in questo momento? –
La risposta che ho elaborato sulla base del tuo suggerimento dovrebbe spiegare le cose. Sono anche interessato all'approccio ActiveSupport :: Concern. – barelyknown