Counter caching is a common practice in Rails, used to keep track of counts such as the number of comments on a post or likes on a video. Rails 7.1 provides built-in methods like increment_counter
and decrement_counter
for updating counters without loading records into memory. However, before Rails 7.1, these methods could only update by a value of 1.
In scenarios where counter caches needed to be incremented or decremented by amounts greater than 1, such as recalculating counts or applying bulk updates, we often turned to workarounds or relied on gems like counter_culture
. With the introduction of the by
argument in Rails 7.1, managing these cases is now much simpler.
Before Rails 7.1:
By default, increment_counter
and decrement_counter
only supported updates by 1. To increment or decrement by custom amounts, we had to:
1) Use Raw SQL:
This was efficient but required direct SQL manipulation, reducing code clarity.
2) Fetch and Update the Record:
While more readable, this approach was less performant, especially for bulk updates.
3) Rely on Gems like counter_culture
:
The counter_culture gem was widely used for advanced counter caching scenarios, such as conditional counters or updates across associations:
Although powerful, introducing external dependencies added complexity.
After Rails 7.1:
Rails 7.1 allows increment_counter and decrement_counter to accept a by
argument, allowing updates by any amount in a single, clean line of code. We simply pass the desired number as the by
argument.
Incrementing a Counter:
This will increase the comments_count column of the record with id: 10
by 5.
Decrementing a Counter:
This will decrease the comments_count column of the record with id: 10
by 3.