Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>From the <a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-belongs_to" rel="noreferrer">fine manual</a>:</p> <blockquote> <p><strong>:counter_cache</strong></p> <p>Caches the number of belonging objects on the associate class through the use of <code>increment_counter</code> and <code>decrement_counter</code>. The counter cache is incremented when an object of this class is created and decremented when it’s destroyed.</p> </blockquote> <p>There's no mention of updating the cache when an object is moved from one owner to another. Of course, the Rails documentation is often incomplete so we'll have to look at the source for confirmation. When you say <code>:counter_cache =&gt; true</code>, you <a href="https://github.com/rails/rails/blob/74e46e51564b38ee0af70387634e0e4138c31742/activerecord/lib/active_record/associations/builder/belongs_to.rb#L15" rel="noreferrer">trigger a call to the private <code>add_counter_cache_callbacks</code> method</a> and <a href="https://github.com/rails/rails/blob/74e46e51564b38ee0af70387634e0e4138c31742/activerecord/lib/active_record/associations/builder/belongs_to.rb#L23" rel="noreferrer"><code>add_counter_cache_callbacks</code> does this</a>:</p> <ol> <li>Adds an <code>after_create</code> callback which calls <a href="http://api.rubyonrails.org/classes/ActiveRecord/CounterCache.html#method-i-increment_counter" rel="noreferrer"><code>increment_counter</code></a>.</li> <li>Adds an <code>before_destroy</code> callback which calls <a href="http://api.rubyonrails.org/classes/ActiveRecord/CounterCache.html#method-i-decrement_counter" rel="noreferrer"><code>decrement_counter</code></a>.</li> <li>Calls <a href="http://api.rubyonrails.org/classes/ActiveRecord/ReadonlyAttributes/ClassMethods.html#method-i-attr_readonly" rel="noreferrer"><code>attr_readonly</code></a> to make the counter column readonly.</li> </ol> <p>I don't think you're expecting too much, you're just expecting ActiveRecord to be more complete than it is.</p> <p>All is not lost though, you can fill in the missing pieces yourself without too much effort. If you want to allow reparenting and have your counters updated, you can add a <code>before_save</code> callback to your ExhibitorRegistration that adjusts the counters itself, something like this (untested demo code):</p> <pre><code>class ExhibitorRegistration &lt; ActiveRecord::Base belongs_to :event, :counter_cache =&gt; true before_save :fix_counter_cache, :if =&gt; -&gt;(er) { !er.new_record? &amp;&amp; er.event_id_changed? } private def fix_counter_cache Event.decrement_counter(:exhibitor_registration_count, self.event_id_was) Event.increment_counter(:exhibitor_registration_count, self.event_id) end end </code></pre> <p>If you were adventurous, you could patch something like that into <code>ActiveRecord::Associations::Builder#add_counter_cache_callbacks</code> and submit a patch. The behavior you're expecting is reasonable and I think it would make sense for ActiveRecord to support it.</p>
 

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