7

I have the table users and scores. Here are the associations:

belongs_to :user #score model
has_many :scores #user model

The table users has the column called scores_count. In this column I store the sum of all values in the table scores.

I wanted to use this way for storing the sum of all scores in the column scores_count: :counter_cache => true

But :counter_cache => true saving only the count of rows in the table scores. Is there any similar method for storing the sum of all values from the table scores? Or this task I have to implement by myself?

user984621
  • 46,344
  • 73
  • 224
  • 412

2 Answers2

11

You could use counter_culture gem.

class Score < ActiveRecord::Base
  belongs_to :user
  counter_culture :user, column_name: 'scores_sum', delta_column: 'score_value'
end
denis.peplin
  • 9,585
  • 3
  • 48
  • 55
  • Hi Denis! I checked out the counter_culture gem and it seems this only supports 1 column am I right? I have multiple associations which have a "costs" column and I would like to combine multiple association sums of "costs" inside 1 column on the parent association. Do you know if this is possible with counter_culture? I checked the specs but nothing indicates something like this is possible. – Jens Jan 05 '23 at 09:26
  • @Jens, I wasn't using Rails for more than six ears now, can't answer your question, sorry. – denis.peplin Jan 10 '23 at 17:55
  • No worries! I wrote my own implementation of caching specific columns for my scenario. I noticed I couldn't use counter culture for the problem I had since some columns needed different calculations based on a given type. Which counter culture doesn't support. – Jens Jan 22 '23 at 11:07
6

No. You'll have to implement it yourself. Counter-cache is for storing the number of associated records only. You could implement it using a callback on Score to update the associated User. See also How can I cache a calculated column in rails?

Further, unless you have noticeable performance issues with summing each time, avoid using a cache like this. It's just something that can easily go wrong and get out-of-date. It's not worth the trouble if you don't really need it.

Community
  • 1
  • 1
Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
  • Ok, thank you for the info. I'd like to ask just - is in this case better to do it with a method (I save the new record to **scores** table and then I will run the method for recounting all the associated values in the **scores** table and save the amount into the **users** table) or through **callback**, as you mentioned above (I didn't work with callback yet)? Which variant is better/faster? – user984621 Jun 13 '12 at 16:54
  • Callback. You could set a callback for any save action on the record, instead of having to deal with calling some method on each action manually. Callbacks are seamless and less error-prone. – Andrew Marshall Jun 13 '12 at 16:59
  • `Further, unless you have noticeable performance issues with summing each time, avoid using a cache like this.` what if I want to sort the active records using that calculated value? any tips for that? @AndrewMarshall – buncis Jan 28 '22 at 11:13