2011-07-14 9 views
5

Estoy usando Kaminari para paginar algunos resultados de una consulta en la que estoy seleccionando registros distintos. Considere el siguiente código de controlador:Obligar a ActiveRecord a contar 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 mejor solución que se me ocurre es pasar :distinct => true a count, como en this pull request, que fue rechazada por el desarrollador de Kaminari. This SO question discute el problema subyacente. This line of code es la llamada ofensiva al count.

¿Hay alguna solución alternativa que proporcione a Kaminari el recuento correcto que no implique parchear Kaminari? Gracias.

ACTUALIZACIÓN:

  • El uso de un instrumento llamado "recuento" es una gran sugerencia, pero no funciona cuando se le llama en una ActiveRecord :: Relation. Funciona cuando lo llamo a mi clase de modelo, pero eso no ayuda.

Respuesta

0

que sugeriría un ámbito en el Modelo

Esto podría confundir las cosas aunque por lo que desea tener cuidado

alcance: ("cosas distintas *") contar, seleccione

Para obtener más información, busque here

+1

¿Se supone que esto es más que un comentario? – apneadiving

+0

Sí, si los OP tuvieran que definir un alcance en el Modelo y nombrarlo contar, entonces podrían controlar lo que hace la biblioteca cuando intenta obtener un recuento del modelo. – LeakyBucket

+0

continúa dando detalles y esto podría estar bien: se supone que las respuestas son claras. De lo contrario, da pistas como comentarios. – apneadiving

3

, consulte la siguiente url.

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

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

Para Rails 3.1.0, cree Rails.root/initializers/kaminari_for_distinct.rb. Y use el siguiente código.

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 
Cuestiones relacionadas