Usted tiene algunas opciones diferentes para saltarse una actualización de la memoria caché de venta libre, y el que usted elija realmente depende de cómo quiera estructurar su aplicación. Discutiré las diferentes formas en que puede sortear el contador de caché y mencionar algunas de las consideraciones que puede querer hacer al hacerlo.
Básicamente, hay tres formas diferentes que puede omitir la actualización de la memoria caché contador:
- Monkey patch your model to disable the counter cache callback
- Use an update method that doesn't trigger callbacks
- definir un modelo que apunta alternativa a la misma mesa que no tiene la mismo comportamiento de devolución de llamada, y usar eso cuando la inserción masiva en la base de datos
Tenga en cuenta que las dos primeras opciones anteriores son más g generalmente relacionado con la desactivación de devoluciones de llamadas en ActiveRecord, y esto tiene sentido porque el contador de caché se implementa internamente mediante una devolución de llamada.
Cuando Rails carga un modelo que tiene asociaciones con un contador de caché, define dinámicamente los métodos de devolución de llamada. Si desea deshabilitar estos como una devolución de llamada, primero debe averiguar cuáles son los nombres de devolución de llamada.
Existen dos formas principales de averiguar qué métodos Rails ha definido para implementar estas devoluciones de llamada. Puede leer la fuente de Rails para averiguar los nombres que va a generar a través de la intorpolación de String, o puede usar la introspección para descubrir a qué métodos responde su clase. Daré un ejemplo de cómo puede usar la introspección para averiguar las devoluciones de llamada definidas por ActiveRecord para implementar automáticamente el almacenamiento en caché.
Supongamos que tiene una clase llamada SpecialReply que desciende de una clase de respuesta que desciende de ActiveRecord :: Base (this example comes from the test suite with Rails). Tiene una columna de caché mostrador como se define a continuación:
class SpecialReply < ::Reply
belongs_to :special_topic, :foreign_key => 'parent_id', :counter_cache => 'replies_count'
end
En la consola, se puede ver lo que los métodos de la clase responde a mediante el uso de .methods
. Esto va a producir una gran cantidad de ruido, ya que cada instancia de Object
ya responde a una gran cantidad de métodos, por lo que puede reducir la lista de la siguiente manera:
1.9.3-p194 :001 > sr = SpecialReply.new
1.9.3-p194 :002 > sr.methods - Object.methods
En la segunda línea que está diciendo, espectáculo todos los métodos a los que responde mi instancia de SpecialReply, menos aquellos a los que responden todos los objetos. Esto a menudo ayuda con la introspección al filtrar métodos que no son particulares del tipo de clase que estás viendo.
Desafortunadamente, incluso después de este filtrado hay mucho ruido debido a los métodos que ActiveRecord agrega a todas sus clases descendientes. En este caso grep
es útil - ya ActiveRecord amablemente crea métodos de devolución de llamada de venta libre que contienen la cadena counter_cache
(see the meta-programming used by ActiveRecord to generate a counter cache method for a belongs_to
association), se puede averiguar las devoluciones de llamada definidos relacionados para contrarrestar cachés con lo siguiente:
1.9.3-p194 :001 > sr = SpecialReply.new
1.9.3-p194 :002 > sr.methods.map(&:to_s).grep(/counter_cache/)
en cuenta que ya grep
opera en una Cadena, y methods
devuelve una matriz de nombres de métodos de símbolos, primero usamos un to_proc
(&:
) para convertir todos los Símbolos a Cadenas y luego eliminar los que contienen counter_cache
. Eso me deja con los siguientes métodos que parecen que fueron probablemente auto-generado por ActiveRecord como devoluciones de llamada para la implementación de contador de almacenamiento en caché:
belongs_to_counter_cache_after_create_for_special_topic
belongs_to_counter_cache_before_destroy_for_special_topic
belongs_to_counter_cache_after_create_for_topic
belongs_to_counter_cache_before_destroy_for_topic
belongs_to_counter_cache_after_create_for_topic_with_primary_key
belongs_to_counter_cache_before_destroy_for_topic_with_primary_key
usted debería ser capaz de seguir un proceso similar en su programa para determinar los nombres de los métodos añadidos por ActiveRecord para que pueda eliminarlos después de existing instructions for removing callbacks.
Su elección entre las opciones anteriores realmente depende de la estructura de su programa, y las compensaciones que está dispuesto a considerar para una mayor eficiencia de carga de datos. Digno de mención es que las dos primeras opciones pueden hacer que su código sea menos legible modificando el comportamiento de una clase desde afuera (parche de mono) y puede hacer que su sistema sea inestable evitando las reglas comerciales (actualizaciones de las columnas de caché) en las actualizaciones de datos. Por estas razones, pensaría si podría crear otra clase para cargar sus datos de una manera optimizada, al tiempo que minimiza los impactos sobre la legibilidad o la coherencia de los datos.
¿Has resuelto esto? El mismo problema... –