:counter_cache => true for storing sum
Asked Answered
A

2

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?

Achromaticity answered 13/6, 2012 at 16:26 Comment(1)
You could just add a callback..Successive
W
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.

Wagshul answered 13/6, 2012 at 16:39 Comment(3)
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?Achromaticity
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.Wagshul
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? @AndrewMarshallArdennes
D
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
Dodie answered 3/3, 2015 at 11:25 Comment(3)
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.Barefoot
@Jens, I wasn't using Rails for more than six ears now, can't answer your question, sorry.Dodie
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.Barefoot
W
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.

Wagshul answered 13/6, 2012 at 16:39 Comment(3)
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?Achromaticity
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.Wagshul
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? @AndrewMarshallArdennes

© 2022 - 2024 — McMap. All rights reserved.