counter_culture icon indicating copy to clipboard operation
counter_culture copied to clipboard

Incorrect count when using ID in the dynamic column name proc

Open lserman opened this issue 2 years ago • 0 comments

Hello, our model has messages that belong to groups and we want to track the group's outbound message count, but only count messages for each recipient once per group (sending a message to the same recipient in the same group multiple times should only increment the groups message count once).

To do this our dynamic column count looked like this:

counter_cache :group, column_name: message -> { message.counter_cache_column_name }

def counter_cache_column_name
  group.messages.where(recipient: recipient).where.not(id: id).exists? nil : :messages_count
end

After we create the message which increments the counter by 1, we send it off to Sidekiq where it is updated with it's delivery timestamp. At this point, the counter increments to 2.

This gem uses ActiveRecord's dup to check if the cache column has changed after each update. dup does not copy the record's ID, instead it sets id to nil. Because of that, the cache column was always "changing" as the dynamic column was checking where id IS NOT NULL, unexpectedly leading to a nil column name vs. the non-dupes column name of messages_count.

I am not sure of the proper fix or if there was a better way to get this functionality without running into this issue, but at the very least I'd like to document this behavior here for the next person as it was quite the goose chase.

lserman avatar Jun 16 '22 04:06 lserman