2011-07-14 8 views
5

Farklı kayıtları seçtiğim bir sorgudan bazı sonuçları sıralamak için Kaminari kullanıyorum.ActiveRecord'ı farklı olarak saymaya zorlayarak (Kaminari ile)

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

Ben Kaminari geliştiricisi tarafından reddedildi this pull request, olduğu gibi count için :distinct => true geçmektir düşünebildiğim en iyi çözüm: Aşağıdaki kontroller kodu göz önünde bulundurun. This SO question temel sorunu ele almaktadır. This line of code, count'a giden çağrıdır.

Kaminari'ye Kaminari yamasını içermeyen doğru sayım sağlayacak herhangi bir geçici çözüm var mı? Teşekkürler.

GÜNCELLEME: "sayılan" olarak adlandırılan bir kapsam kullanılması

  • harika bir öneri ancak bir ActiveRecord :: İlişki çağrıldığında çalışmaz. Model sınıfıma çağrıldığında işe yarıyor ama bu işe yaramıyor.

cevap

0

Ben Modeli üzerinde bir kapsam öneririm

yüzden dikkatli olmasını istiyorum gerçi bu şeyleri karıştırmayın olabilir

kapsamı: ("DISTINCT şeyler *") seçin saymak

Daha fazla bilgi için, lütfen aşağıdaki URL'ye bakın: here

+1

Bunun bir yorumdan fazlası olması gerekiyor mu? – apneadiving

+0

Evet, eğer OP, Model üzerinde bir kapsam tanımlasaydı ve saydığı isim ise, modelden bir sayı elde etmeye çalıştığında kütüphanenin ne yaptığını kontrol edebilirdi. – LeakyBucket

+0

detay vermeye devam ediyor ve bu tamam olabilir: cevapların açık olması gerekiyor. Aksi halde yorum olarak ipuçları verin. – apneadiving

3

.

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

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

ama onlar Raylar 3.1.0 üzerinde faild.

Rails 3.1.0 için Rails.root/initializers/kaminari_for_distinct.rb dosyasını oluşturun. Ve aşağıdaki kodu kullanın.

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 
İlgili konular