Skip to content

Commit cabc184

Browse files
committed
Make increment_counter/decrement_counter accept an amount argument
1 parent 490804f commit cabc184

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

activerecord/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
* Make `increment_counter`/`decrement_counter` accept an amount argument
2+
3+
```ruby
4+
Post.increment_counter(:comments_count, 5, by: 3)
5+
```
6+
7+
*fatkodima*
8+
19
* Add support for `Array#intersect?` to `ActiveRecord::Relation`.
210

311
`Array#intersect?` is only available on Ruby 3.1 or later.

activerecord/lib/active_record/counter_cache.rb

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ def update_counters(id, counters)
126126
#
127127
# * +counter_name+ - The name of the field that should be incremented.
128128
# * +id+ - The id of the object that should be incremented or an array of ids.
129+
# * <tt>:by</tt> - The amount by which to increment the value. Defaults to +1+.
129130
# * <tt>:touch</tt> - Touch timestamp columns when updating.
130131
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
131132
# touch that column or an array of symbols to touch just those ones.
@@ -136,10 +137,14 @@ def update_counters(id, counters)
136137
# DiscussionBoard.increment_counter(:posts_count, 5)
137138
#
138139
# # Increment the posts_count column for the record with an id of 5
140+
# # by a specific amount.
141+
# DiscussionBoard.increment_counter(:posts_count, 5, by: 3)
142+
#
143+
# # Increment the posts_count column for the record with an id of 5
139144
# # and update the updated_at value.
140145
# DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
141-
def increment_counter(counter_name, id, touch: nil)
142-
update_counters(id, counter_name => 1, touch: touch)
146+
def increment_counter(counter_name, id, by: 1, touch: nil)
147+
update_counters(id, counter_name => by, touch: touch)
143148
end
144149

145150
# Decrement a numeric field by one, via a direct SQL update.
@@ -151,6 +156,7 @@ def increment_counter(counter_name, id, touch: nil)
151156
#
152157
# * +counter_name+ - The name of the field that should be decremented.
153158
# * +id+ - The id of the object that should be decremented or an array of ids.
159+
# * <tt>:by</tt> - The amount by which to increment the value. Defaults to +1+.
154160
# * <tt>:touch</tt> - Touch timestamp columns when updating.
155161
# Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
156162
# touch that column or an array of symbols to touch just those ones.
@@ -161,10 +167,14 @@ def increment_counter(counter_name, id, touch: nil)
161167
# DiscussionBoard.decrement_counter(:posts_count, 5)
162168
#
163169
# # Decrement the posts_count column for the record with an id of 5
170+
# by a specific amount.
171+
# DiscussionBoard.decrement_counter(:posts_count, 5, by: 3)
172+
#
173+
# # Decrement the posts_count column for the record with an id of 5
164174
# # and update the updated_at value.
165175
# DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
166-
def decrement_counter(counter_name, id, touch: nil)
167-
update_counters(id, counter_name => -1, touch: touch)
176+
def decrement_counter(counter_name, id, by: 1, touch: nil)
177+
update_counters(id, counter_name => -by, touch: touch)
168178
end
169179

170180
def counter_cache_column?(name) # :nodoc:

activerecord/test/cases/counter_cache_test.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,24 @@ class ::SpecialReply < ::Reply
4040
end
4141
end
4242

43+
test "increment counter by specific amount" do
44+
assert_difference "@topic.reload.replies_count", +2 do
45+
Topic.increment_counter(:replies_count, @topic.id, by: 2)
46+
end
47+
end
48+
4349
test "decrement counter" do
4450
assert_difference "@topic.reload.replies_count", -1 do
4551
Topic.decrement_counter(:replies_count, @topic.id)
4652
end
4753
end
4854

55+
test "decrement counter by specific amount" do
56+
assert_difference "@topic.reload.replies_count", -2 do
57+
Topic.decrement_counter(:replies_count, @topic.id, by: 2)
58+
end
59+
end
60+
4961
test "reset counters" do
5062
# throw the count off by 1
5163
Topic.increment_counter(:replies_count, @topic.id)

0 commit comments

Comments
 (0)