Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

reset_counter_cache

#1211

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.

Reported by Trevor Turk · October 14th, 2008 @ 10:18 PM

State: committed
Milestone: 2.3.6
Assigned to: Pratik Pratik
Importance: none

Activity

  1. Trevor Turk
    Trevor Turk

    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!

    October 22nd, 2008 @ 11:31 PM

  2. Pratik
    Pratik
    • Assigned user set to Pratik

    December 11th, 2008 @ 05:29 PM

  3. Pratik
    Pratik
    • State changed from new to incomplete

    Patch please.

    March 13th, 2009 @ 11:14 AM

  4. Mike Breen
    Mike Breen
    • Tag set to active_record, counter_cache, patch

    This patch adds Model.reset_counter_cache(:association_name).

    March 29th, 2009 @ 02:00 PM

  5. Pratik
    Pratik
    • State changed from incomplete to open

    March 29th, 2009 @ 02:14 PM

  6. Sascha Konietzke
    Sascha Konietzke

    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")
    

    April 14th, 2009 @ 01:18 PM

  7. Mike Breen
    Mike Breen

    Thanks for pointing that out Sascha. I've updated the patch to set the counter to zero first.

    April 14th, 2009 @ 03:43 PM

  8. Max Lapshin
    Max Lapshin

    What for to reset counter to 0? Maybe better is real resetting to exact number of records?

    April 23rd, 2009 @ 10:47 AM

  9. Mike Breen
    Mike Breen

    @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 using update_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.

    April 23rd, 2009 @ 12:57 PM

  10. Mike Breen
    Mike Breen

    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

    May 20th, 2009 @ 03:38 PM

  11. Mike Breen
    Mike Breen
    • Tag changed from active_record, counter_cache, patch to active_record, bugmash, counter_cache, patch

    September 26th, 2009 @ 02:14 PM

  12. Repository
    Repository
    • State changed from open to committed

    December 2nd, 2009 @ 08:42 PM

  13. Repository
  14. Jeremy Kemper
    Jeremy Kemper
    • Milestone changed from 2.x to 2.3.6

    December 2nd, 2009 @ 08:56 PM

  15. Gabe da Silveira
    Gabe da Silveira

    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...

    December 2nd, 2009 @ 11:45 PM

  16. Jeremy Kemper
    Jeremy Kemper
    • State changed from committed to open

    Nice revisions. Could you forward-port to master too?

    December 3rd, 2009 @ 12:12 AM

  17. Gabe da Silveira
    Gabe da Silveira

    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.

    December 3rd, 2009 @ 05:39 AM

  18. Mike Breen
    Mike Breen

    +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?

    December 3rd, 2009 @ 01:59 PM

  19. Gabe da Silveira
    Gabe da Silveira

    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.

    December 3rd, 2009 @ 04:14 PM

  20. Mike Breen
    Mike Breen

    I think how you just put it is perfect :)

    Thanks for taking the time to clarify what exactly the worse case scenario is.

    December 3rd, 2009 @ 07:23 PM

  21. Repository
    Repository
    • 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 reset_counter_cache state:committed]

    Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
    http://github.com/rails/rails/commit/32395899d7c97f69b508b7d7f9b771...

    December 4th, 2009 @ 07:26 AM

  22. Repository
    Repository

    (from [43d2cb8e93e7ff3da4d5b4e3c25272b27812adfc]) Replace reset_counter_cache with reset_counters that has API inline with existing update_counters method

    [#1211 reset_counter_cache state:committed]

    Signed-off-by: Jeremy Kemper jeremy@bitsweat.net
    http://github.com/rails/rails/commit/43d2cb8e93e7ff3da4d5b4e3c25272...

    December 4th, 2009 @ 07:26 AM

  23. Mislav
    Mislav

    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"

    April 17th, 2010 @ 02:15 AM

  24. af001
    af001

    私の中で、総合評価のとっても低いアバアバクロホリスタークロ銀座店。アバクロは大好きなんですけどね。一昨日の東京駅付近での打ち合わせの後、散歩がてら久々に行ってきました。そしたらビックリ!相変わらアバクロず、踊っているだけの店員さんとかもいましたが、

    May 5th, 2011 @ 03:00 AM