Recientemente me encontré con este mismo problema (Rails 3.2.3). Parece que aún no se ha solucionado, así que tuve que seguir adelante y solucionarlo. A continuación se muestra cómo modifiqué ActiveRecord :: Base y utilicé la devolución de llamada after_update para mantener sincronizados mis counter_caches.
Extender ActiveRecord :: Base
Crear un nuevo archivo lib/fix_counters_update.rb
con lo siguiente:
module FixUpdateCounters
def fix_updated_counters
self.changes.each {|key, value|
# key should match /master_files_id/ or /bibls_id/
# value should be an array ['old value', 'new value']
if key =~ /_id/
changed_class = key.sub(/_id/, '')
changed_class.camelcase.constantize.decrement_counter(:"#{self.class.name.underscore.pluralize}_count", value[0]) unless value[0] == nil
changed_class.camelcase.constantize.increment_counter(:"#{self.class.name.underscore.pluralize}_count", value[1]) unless value[1] == nil
end
}
end
end
ActiveRecord::Base.send(:include, FixUpdateCounters)
El código anterior utiliza el método ActiveModel::Dirtychanges
que devuelve un hash que contiene el atributo cambiado y una matriz tanto del valor antiguo como del nuevo valor. Al probar el atributo para ver si se trata de una relación (es decir, termina con/_id /), puede determinar condicionalmente si se debe ejecutar decrement_counter
y/o increment_counter
. Es esencial probar la presencia de nil
en la matriz; de lo contrario, se producirán errores.
Añadir a Inicializadores
Crear un nuevo archivo config/initializers/active_record_extensions.rb
con lo siguiente:
require 'fix_update_counters'
Añadir a modelos
Para cada modelo desea que los cachés de contador actualizado Agregar la devolución de llamada:
class Comment < ActiveRecord::Base
after_update :fix_updated_counters
....
end
que probablemente será un error si container_id/container_id_was es nula. – Zequez