diff --git a/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb b/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb index 6c3c15e..ed35fbe 100644 --- a/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb +++ b/kaminari-activerecord/lib/kaminari/activerecord/active_record_relation_methods.rb @@ -32,12 +32,15 @@ module Kaminari c = c.limit(max_pages * limit_value) if max_pages && max_pages.respond_to?(:*) - # Handle grouping with a subquery - @total_count = if c.group_values.any? - c.model.from(c.except(:select).select("1")).count - else - c.count(column_name) - end + # .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 end # Turn this Relation to a "without count mode" Relation. diff --git a/kaminari-core/test/fake_app/active_record/models.rb b/kaminari-core/test/fake_app/active_record/models.rb index 374ac18..56cd328 100644 --- a/kaminari-core/test/fake_app/active_record/models.rb +++ b/kaminari-core/test/fake_app/active_record/models.rb @@ -26,6 +26,12 @@ class Authorship < ActiveRecord::Base belongs_to :user belongs_to :book end +class CurrentAuthorship < ActiveRecord::Base + self.table_name = 'authorships' + belongs_to :user + belongs_to :book + default_scope -> { where(deleted_at: nil) } +end class Readership < ActiveRecord::Base belongs_to :user belongs_to :book @@ -43,6 +49,11 @@ end class User::Address < ActiveRecord::Base belongs_to :user end +class Animal < ActiveRecord::Base; end +class Mammal < Animal; end +class Dog < Mammal; end +class Cat < Mammal; end +class Insect < Animal; end # a class that uses abstract class class Product < ActiveRecord::Base @@ -63,9 +74,10 @@ class CreateAllTables < ActiveRecord::VERSION::MAJOR >= 5 ? ActiveRecord::Migrat create_table(:users) {|t| t.string :name; t.integer :age} create_table(:books) {|t| t.string :title} create_table(:readerships) {|t| t.integer :user_id; t.integer :book_id } - create_table(:authorships) {|t| t.integer :user_id; t.integer :book_id } + create_table(:authorships) {|t| t.integer :user_id; t.integer :book_id; t.datetime :deleted_at } create_table(:user_addresses) {|t| t.string :street; t.integer :user_id } create_table(:devices) {|t| t.string :name; t.integer :age} + create_table(:animals) {|t| t.string :type; t.string :name} end end CreateAllTables.up diff --git a/kaminari-core/test/models/active_record/active_record_relation_methods_test.rb b/kaminari-core/test/models/active_record/active_record_relation_methods_test.rb index 8093961..68febba 100644 --- a/kaminari-core/test/models/active_record/active_record_relation_methods_test.rb +++ b/kaminari-core/test/models/active_record/active_record_relation_methods_test.rb @@ -100,6 +100,22 @@ if defined? ActiveRecord assert_equal 2, Authorship.group(:user_id).having("COUNT(book_id) >= 3").page(1).total_count end + test 'calculating total_count with GROUP BY ... HAVING clause with model that has default scope' do + assert_equal 2, CurrentAuthorship.group(:user_id).having("COUNT(book_id) >= 3").page(1).total_count + 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) } + + assert_equal 3, Mammal.group(:name).page(1).total_count + end + test 'total_count with max_pages does not add LIMIT' do begin subscriber = ActiveSupport::Notifications.subscribe 'sql.active_record' do |_, __, ___, ____, payload|