Skip to content

Commit

Permalink
Merge pull request #4 from LukinEgor/feature/add-with-slotted-counter…
Browse files Browse the repository at this point in the history
…s-scope

add with_slotted_counters scope
  • Loading branch information
egor-lukin authored Oct 4, 2022
2 parents f7828e4 + 124ce0e commit 0572b68
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 6 deletions.
5 changes: 2 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ Under the hood, a row in the `slotted_counters` table is created associated with
**NOTE:** Reading the current value performs SQL query once:

```ruby
user.comments_count #=> select count from slotted_counters where ...
user.comments_count #=> select * from slotted_counters where ...
user.comments_count #=> no sql
```

If you want to want preload counters for multiple records, you can use a convinient `#with_slotted_counters` method:
If you want to want preload counters for multiple records, you can use a convenient `#with_slotted_counters` method:

```ruby
User.all.with_slotted_counters(:comments).find_each do
Expand All @@ -73,7 +73,6 @@ Using `counter_cache: true` on `belongs_to` associations also works as expected.
## Limitations / TODO

- Add `reset_counters` implementation
- Add `with_slotted_counters` scope
- Rails 6 support

## Contributing
Expand Down
7 changes: 4 additions & 3 deletions lib/activerecord_slotted_counters/has_slotted_counter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ def has_slotted_counter(counter_type)
counter_name = slotted_counter_name(counter_type)
association_name = slotted_counter_association_name(counter_type)

has_many association_name, **SLOTTED_COUNTERS_ASSOCIATION_OPTIONS
has_many association_name, ->(model) { associated_records(counter_name, model.id, model.class.to_s) }, **SLOTTED_COUNTERS_ASSOCIATION_OPTIONS

scope :with_slotted_counters, ->(counter_type) { preload(association_name) }

_slotted_counters << counter_type

Expand Down Expand Up @@ -153,8 +155,7 @@ def read_slotted_counter(counter_type)
return counter
end

counter_name = slotted_counter_name(counter_type)
scope = send(association_name).associated_records(counter_name, id, self.class.to_s)
scope = send(association_name)
scope.sum(:count)
end
end
Expand Down
13 changes: 13 additions & 0 deletions spec/slotted_counter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,17 @@
expect(article.comments_count).to eq(comments_count)
expect(article.views_count).to eq(views_count)
end

it "must preload slotted counters" do
article = WithSlottedCounter::Article.create!
WithSlottedCounter::Article.increment_counter(:comments_count, article.id)

WithSlottedCounter::Article.all.find_each do |article|
expect(article.comments_slotted_counters.loaded?).to be_falsy
end

WithSlottedCounter::Article.all.with_slotted_counters(:comments).find_each do |article|
expect(article.comments_slotted_counters.loaded?).to be_truthy
end
end
end

0 comments on commit 0572b68

Please sign in to comment.