This project is archived and is in readonly mode.
reset_counter_cache
Reported by Trevor Turk | October 14th, 2008 @ 10:18 PM | in 2.3.6
In reference to: http://rails.lighthouseapp.com/p... and http://groups.google.com/group/r...
It would be nice to have something like Model.reset_counter_cache(:column_name)
This would be useful when adding a new counter_cache, or if the count was off for whatever reason. Note: adding documentation in the counter_cache area about this would be sweet, too.
Comments and changes to this ticket
-
Trevor Turk October 22nd, 2008 @ 11:31 PM
I gave this the old college try and wasn't able to figure it out. The problem is getting the table name for the association with the column name for the counter. Good luck to anyone else who'd like to give it a shot - I'd be very interested to see how it's done!
-
Pratik December 11th, 2008 @ 05:29 PM
- Assigned user set to Pratik
-
Mike Breen March 29th, 2009 @ 02:00 PM
- Tag set to active_record, counter_cache, patch
This patch adds Model.reset_counter_cache(:association_name).
-
Pratik March 29th, 2009 @ 02:14 PM
- State changed from incomplete to open
-
Sascha Konietzke April 14th, 2009 @ 01:18 PM
I had some problems with counter cache recently myself.
Mike, your patch doesn't seem to account that update_counters increments or decrements the counters by the given amount and doesn't set them to the new value that you get when counting the associations again.
There might be another method to really set the counters or it is necessary to do something like this before using update_counters:
update_all("#{association_name}_count = 0")
-
Mike Breen April 14th, 2009 @ 03:43 PM
Thanks for pointing that out Sascha. I've updated the patch to set the counter to zero first.
-
Max Lapshin April 23rd, 2009 @ 10:47 AM
What for to reset counter to 0? Maybe better is real resetting to exact number of records?
-
Mike Breen April 23rd, 2009 @ 12:57 PM
@Max
reset_counter_cache
does reset to the exact number of records, but only after resetting it to zero first.After thinking about this there is really no longer a need to reset the counter_cache to zero initially. It made sense when
reset_counter_cache
was usingupdate_counters
but since that is no longer the case the reset to zero is not necessary.Thanks for taking the time to look at the patch.
-
Mike Breen May 20th, 2009 @ 03:38 PM
After talking with the mysterious "noob" on irc I've updated the patch:
- use #find_each
- use #reflect_on_association to get the counter_cache column name
- use connection.update to issue the update sql statement
-
Mike Breen September 26th, 2009 @ 02:14 PM
- Tag changed from active_record, counter_cache, patch to active_record, bugmash, counter_cache, patch
-
Repository December 2nd, 2009 @ 08:42 PM
- State changed from open to committed
(from [1db3a27961a9916d6dff0da056a3595a78e7886c]) Implement ActiveRecord#reset_counter_cache
[#1211 state:committed]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
http://github.com/rails/rails/commit/1db3a27961a9916d6dff0da056a359... -
Repository December 2nd, 2009 @ 08:42 PM
(from [50c28e78c7aa40dc329facbe6131d657d5629bd4]) Implement ActiveRecord#reset_counter_cache
[#1211 state:committed]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
http://github.com/rails/rails/commit/50c28e78c7aa40dc329facbe6131d6... -
Jeremy Kemper December 2nd, 2009 @ 08:56 PM
- Milestone changed from 2.x to 2.3.6
-
Gabe da Silveira December 2nd, 2009 @ 11:45 PM
Thanks for the work on this everybody, but I don't agree with the implementation. Resetting all the counter caches like this is not performant. At best you will incur some overhead when all you want is to update a single counter cache, at worst this will be a major ordeal requiring hours or days to run.
It seems to me the API should be inline with update_counters. Attached is a subsequent patch against 2-3-stable to bring the APIs more inline. This lets you run against a single row and update multiple counter caches. The original functionality is then trivial to implement:
find_each { |f| reset_counters(f.id, association) }
Now a full-reset that ran by means of a single UPDATE with a GROUPed sub-query to perform the counting — that would be worth pursuing if subselects are included in the minimum requirements for ActiveRecord...
-
Jeremy Kemper December 3rd, 2009 @ 12:12 AM
- State changed from committed to open
Nice revisions. Could you forward-port to master too?
-
Gabe da Silveira December 3rd, 2009 @ 05:39 AM
Ugh, having all kinds of Ruby and mysql version headaches. I can't get master to run tests right now. But here is the patch applied to master. If you could run the tests that would be awesome.
-
Mike Breen December 3rd, 2009 @ 01:59 PM
+1 for the new patch.
Although the original ticket was solving a different use case (something that you would run infrequently, possibly during a migration) this is a workable solution to both use cases.
at worst this will be a major ordeal requiring hours or days to run.
-1 for using FUD to make your case. What is this based on? Running this on Amazon's product table?
-
Gabe da Silveira December 3rd, 2009 @ 04:14 PM
What is FUD about the at best / at worst scenario? How would you have me say it?
I don't have time to put together a benchmark, but I've done enough row-wise updates on my app (counts ranging from the thousands to low millions, nothing huge). I don't think it should be controversial to say a very significant percentage of applications are going to have tables with more than a few thousand rows, and that row-wise updates hit scalability issues orders of magnitude before regular selects, updates, joins and other ActiveRecord methods do. And therefore I think the use of find_each should be up to the programmer, which as far as I know is an opinion ActiveRecord respects to-date.
-
Mike Breen December 3rd, 2009 @ 07:23 PM
I think how you just put it is perfect :)
Thanks for taking the time to clarify what exactly the worse case scenario is.
-
Repository December 4th, 2009 @ 07:26 AM
- State changed from open to committed
(from [32395899d7c97f69b508b7d7f9b7711f28586679]) Replace reset_counter_cache with reset_counters that has API inline with existing update_counters method
[#1211 state:committed]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
http://github.com/rails/rails/commit/32395899d7c97f69b508b7d7f9b771... -
Repository December 4th, 2009 @ 07:26 AM
(from [43d2cb8e93e7ff3da4d5b4e3c25272b27812adfc]) Replace reset_counter_cache with reset_counters that has API inline with existing update_counters method
[#1211 state:committed]
Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
http://github.com/rails/rails/commit/43d2cb8e93e7ff3da4d5b4e3c25272... -
Mislav April 17th, 2010 @ 02:15 AM
I've cleaned up
update/reset_counters
code (now with more ActiveRecord/Arel) and fixed two bugs with guessing association names. Changes are in my "counter_cache" branch on GitHub. Rails 2.3.x version is also available in "counter_cache_2-3-stable"
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>
People watching this ticket
Attachments
Referenced by
- 1211 reset_counter_cache [#1211 state:committed]
- 1211 reset_counter_cache [#1211 state:committed]
- 1211 reset_counter_cache [#1211 state:committed]
- 1211 reset_counter_cache [#1211 state:committed]