2011-07-14 21 views
5

私はKaminariを使用して、別のレコードを選択しているクエリからいくつかの結果をページ付けしています。ActiveRecordを別名でカウントするように強制します。

@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) 

私は雷の開発者によって拒否されたthis pull request、のように、count:distinct => trueを通過させることであると考えることができる最高の解決策:以下のコントローラのコードを考えてみましょう。 This SO questionは根本的な問題について論じている。 This line of codecountの問題の呼び出しです。

カミナリにパッチを当てることなくカミンナリに正しいカウントを提供する回避策はありますか?ありがとう。

UPDATE:「カウント」と呼ばれるスコープを使用して

  • は素晴らしい提案ですが、ActiveRecordは::関係に呼び出されたときに動作しません。私のモデルクラスで呼び出されたときに動作しますが、それは役に立ちません。

答えて

0

私はあなたが

範囲慎重になりたいが、これは物事を混乱させる可能性があるモデル

にスコープを示唆している:( "DISTINCTもの*を。")を選択し、カウント

を詳細はこちらhere

+1

これはコメント以上のものですか? – apneadiving

+0

はい、OPがモデル上のスコープを定義して名前を数えた場合、モデルからカウントを取得しようとするときにライブラリが行うことを制御できます。 – LeakyBucket

+0

詳細を続​​けるとOKかもしれません。答えは明確になっているはずです。それ以外の場合は、ヒントをコメントとして入力します。 – apneadiving

3

次のURLを参照してください。

https://github.com/tbeauvais/kaminari/commit/23695cbdc4ff1b9fa58c18d4a3c2f18e21451b8b

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

しかし、彼らはRailsの3.1.0にfaild。

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 
関連する問題