我正在使用Kaminari对查询中的某些结果进行分页,在该查询中我选择了不同的记录。考虑以下 Controller 代码:

@things = Thing.joins... # create a complex query that produces duplicate results

# I want to select distinct results: this produces the correct results
@things = @things.select("DISTINCT things.*")

# when Kaminari calls count, it will run "SELECT COUNT(*)", instead of
# "SELECT COUNT(DISTINCT things.*)" we will get the wrong count and extra pages
@things = @things.page(params[:page]).per(10)

我能想到的最好的解决方案是将:distinct => true传递给count,就像this pull request一样,被Kaminari的开发人员拒绝。 This SO question讨论了潜在的问题。 This line of code是对count的有害调用。

是否有任何变通办法可以为Kaminari提供不涉及修补Kaminari的正确计数?谢谢。

更新:
  • 建议使用范围为“count”的范围,但在ActiveRecord::Relation上调用时不起作用。在我的模型类上调用它时,它可以工作,但这没有帮助。
  • 最佳答案

    请引用以下网址。

    https://github.com/amatsuda/kaminari/pull/77

    https://github.com/tbeauvais/kaminari/commit/23695cbdc4ff1b9fa58c18d4a3c2f18e21451b8b
    但是,它们在Rails 3.1.0上失败了。

    对于Rails 3.1.0,创建Rails.root/initializers/kaminari_for_distinct.rb。
    并使用以下代码。

    module Kaminari
      module ActiveRecordRelationMethods
        extend ActiveSupport::Concern
        module InstanceMethods
          def total_count #:nodoc:
            if distinct_column_name.nil?
              c = except(:offset, :limit).count
            else
              c = except(:offset, :limit).count(distinct_column_name, :distinct => true)
            end
            # .group returns an OrderdHash that responds to #count
            c.respond_to?(:count) ? c.count : c
          end
    
          # Get the column name used in distinct query.
          # This could have been set on the Model class, or the ActiveRecord::Relation
          def distinct_column_name
            @distinct_column || distinct_column
          end
        end
      end
    end
    
    module Kaminari
      module ConfigurationMethods
        extend ActiveSupport::Concern
        module ClassMethods
    
          # Set the name of the column to use during .count()
          # Setting this will cause call to count to use: count(:id, :distinct => true) for all the Models paged queries.
          # Example:
          #   class User < ActiveRecord::Base
          #     use_distinct :id
          #   end
          def use_distinct(column)
            @distinct_column = column
          end
    
          # Returns the distinct column name set on the Model, or nil if not using distinct
          def distinct_column
            @distinct_column
          end
        end
      end
    end
    
    
    module Kaminari
      module PageScopeMethods
        extend ActiveSupport::Concern
        module InstanceMethods
    
          # Set the name of the column to use during .count()
          # Setting this will cause call to count to use: count(:id, :distinct => true)
          # Example: User.page(3).per(5).use_distinct(:id)
          def use_distinct(column)
            @distinct_column = column
            self
          end
        end
      end
    end
    

    关于ruby-on-rails - 强制ActiveRecord进行计数(使用Kaminari),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6699351/

    10-13 04:50