Skip to content

Commit

Permalink
Grouped query performance of total_count, take 2
Browse files Browse the repository at this point in the history
Improved performance for total_count on grouped ActiveRecord::Relation.

This re-implements kaminari#979 using Arel to avoid issues kaminari#1012 and kaminari#1015
  • Loading branch information
bendilley committed May 13, 2020
1 parent 04d86ed commit 8356038
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 16 deletions.
Expand Up @@ -32,15 +32,13 @@ def total_count(column_name = :all, _options = nil) #:nodoc:

c = c.limit(max_pages * limit_value) if max_pages && max_pages.respond_to?(:*)

# .group returns an OrderedHash that responds to #count
c = c.count(column_name)
@total_count = if c.is_a?(Hash) || c.is_a?(ActiveSupport::OrderedHash)
c.count
elsif c.respond_to? :count
c.count(column_name)
else
c
end
# Handle grouping with a subquery
@total_count = if c.group_values.any?
sq = c.except(:select).select("1 AS record").arel.as("subquery")
c.model.connection.select_value Arel::SelectManager.new.from(sq).project(sq[:record].count)
else
c.count(column_name)
end
end

# Turn this Relation to a "without count mode" Relation.
Expand Down
Expand Up @@ -105,13 +105,13 @@ class ActiveRecordRelationMethodsTest < ActiveSupport::TestCase
end

test 'calculating STI total_count with GROUP BY clause' do
{
'Fenton' => Dog,
'Bob' => Dog,
'Garfield' => Cat,
'Bob' => Cat,
'Caine' => Insect
}.each { |name, type| type.create!(name: name) }
[
['Fenton', Dog],
['Bob', Dog],
['Garfield', Cat],
['Bob', Cat],
['Caine', Insect]
].each { |name, type| type.create!(name: name) }

assert_equal 3, Mammal.group(:name).page(1).total_count
end
Expand Down

0 comments on commit 8356038

Please sign in to comment.