Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I recently came across this same problem (Rails 3.2.3). Looks like it has yet to be fixed, so I had to go ahead and make a fix. Below is how I amended ActiveRecord::Base and utilize after_update callback to keep my counter_caches in sync.</p> <p><strong>Extend ActiveRecord::Base</strong></p> <p>Create a new file <code>lib/fix_counters_update.rb</code> with the following:</p> <pre><code>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) </code></pre> <p>The above code uses the <a href="http://api.rubyonrails.org/classes/ActiveModel/Dirty.html">ActiveModel::Dirty</a> method <code>changes</code> which returns a hash containing the attribute changed and an array of both the old value and new value. By testing the attribute to see if it is a relationship (i.e. ends with /_id/), you can conditionally determine whether <code>decrement_counter</code> and/or <code>increment_counter</code> need be run. It is essnetial to test for the presence of <code>nil</code> in the array, otherwise errors will result.</p> <p><strong>Add to Initializers</strong></p> <p>Create a new file <code>config/initializers/active_record_extensions.rb</code> with the following:</p> <p><code>require 'fix_update_counters'</code></p> <p><strong>Add to models</strong></p> <p>For each model you want the counter caches updated add the callback:</p> <pre><code>class Comment &lt; ActiveRecord::Base after_update :fix_updated_counters .... end </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload