2011-07-14 13 views
5

Sto utilizzando Kaminari per impaginare alcuni risultati di una query in cui sto selezionando record distinti. Si consideri il seguente codice di controllo:Forzare ActiveRecord al conteggio distinto (con Kaminari)

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

La soluzione migliore che mi viene in mente è quello di passare :distinct => true-count, come in this pull request, che è stata respinta dallo sviluppatore di Kaminari. This SO question discute il problema sottostante. This line of code è la chiamata all'origine di count.

Esistono soluzioni alternative che forniranno a Kaminari il conteggio corretto che non prevede il patching di Kaminari? Grazie.

UPDATE:

  • Utilizzando un ambito denominato "conteggio" è un grande suggestione, ma non funziona quando viene chiamato su un ActiveRecord :: Relation. Funziona quando viene chiamato sulla mia classe modello, ma ciò non aiuta.

risposta

0

Vorrei suggerire un ambito sul Modello

Questo potrebbe confondere le cose anche se così si vuole stare attenti

campo di applicazione: ("cose ​​distinte *") contare, selezionare

Per ulteriori informazioni vedi here

+1

Si suppone che sia più di un commento? – apneadiving

+0

Sì, se l'OP dovesse definire un ambito sul Modello e denominarlo conteggio, allora sarebbe in grado di controllare cosa fa la libreria quando tenta di ottenere un conteggio dal modello. – LeakyBucket

+0

continua a fornire dettagli e questo potrebbe essere ok: le risposte dovrebbero essere chiare. Altrimenti, fornisci suggerimenti come commenti. – apneadiving

3

fare riferimento al seguente URL.

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

https://github.com/tbeauvais/kaminari/commit/23695cbdc4ff1b9fa58c18d4a3c2f18e21451b8b ma, hanno faild on Rails 3.1.0.

Per Rails 3.1.0, creare Rails.root/initializers/kaminari_for_distinct.rb. E utilizzare il seguente codice.

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 
Problemi correlati