2009-07-07 24 views
7

bastante seguro de que me falta algo muy simple aquí:will_paginate con múltiples modelos (rieles)

Estoy tratando de mostrar una serie de páginas que contienen los casos de dos modelos diferentes - Perfiles y Grupos. Los necesito pidiendo por su atributo de nombre. Pude seleccionar todas las instancias para cada modelo, luego ordenarlas y paginarlas, pero esto se siente descuidado e ineficiente.

Estoy usando mislav-will_paginate, y me preguntaba si hay alguna forma mejor de lograr esto? Algo como:

[Profile, Group].paginate(...) 

sería ideal!

Respuesta

6

Buena pregunta, me encontré con el mismo problema un par de veces. Cada vez, terminé escribiendo mi propia consulta sql basada en uniones sql (funciona bien con sqlite y mysql). Luego, puede utilizar paginará pasando los resultados (http://www.pathf.com/blogs/2008/06/how-to-use-will_paginate-with-non-activerecord-collectionarray/). No olvides realizar la consulta para contar todas las filas.

Algunas líneas de código (no probado)

my_query = "(select posts.title from posts) UNIONS (select profiles.name from profiles)" 
total_entries = ActiveRecord::Base.connection.execute("select count(*) as count from (#{my_query})").first['count'].to_i 

results = ActiveRecord::Base.connection.select_rows("select * from (#{my_query}) limit #{limit} offset #{offset}") 

¿Es overkilled? Tal vez, pero tienes la cantidad mínima de consultas y los resultados son consistentes.

Espero que ayude.

Nota: Si se obtiene el valor de desplazamiento de un parámetro HTTP, debe utilizar sanitize_sql_for_conditions (es decir: la inyección de SQL ....)

0

¿Ha intentado mostrar dos conjuntos diferentes de resultados con sus propios paginators y actualizarlos a través de AJAX? No es exactamente lo que quieres, pero el resultado es similar.

+0

Desafortunadamente eso no lo va a cortar, necesito tener los dos conjuntos de instancias juntas. – Codebeef

1

Puede estar cerca de hacer algo como:

@profiles, @groups = [Profile, Group].map do |clazz| 
    clazz.paginate(:page => params[clazz.to_s.downcase + "_page"], :order => 'name') 
end 

que luego paginate utilizando parámetros de página y profile_pagegroup_page. Usted puede obtener la llamada will_paginate en la vista de utilizar la página correcta usando:

<%= will_paginate @profiles, :page_param => 'profile_page' %> 
.... 
<%= will_paginate @groups, :page_param => 'group_page' %> 

Aún así, no estoy seguro de que hay una gran ventaja frente a la creación de @groups y @profiles individualmente.

1

en mi último proyecto i atrapado en un problema, tuve que paginar múltiples modelos con una sola paginación en mi funcionalidad de búsqueda. debería funcionar de manera que el primer modelo aparezca primero cuando los resultados del primer modelo, un segundo modelo continúe los resultados y el tercero, y así sucesivamente, como un solo feed de búsqueda, al igual que los feeds de Facebook. esta es la función que he creado para hacer esta funcionalidad

def multi_paginate(models, page, per_page) 

    WillPaginate::Collection.create(page, per_page) do |pager| 

    # set total entries 
    pager.total_entries = 0 
    counts = [0] 
    offsets = [] 
    for model in models 
      pager.total_entries += model.count 
      counts << model.count 
      offset = pager.offset-(offsets[-1] || 0) 
      offset = offset>model.count ? model.count : offset 
      offsets << (offset<0 ? 0 : offset) 
    end 

    result = [] 
    for i in 0...models.count 
      result += models[i].limit(pager.per_page-result.length).offset(offsets[i]).to_a 
    end 

    pager.replace(result) 
    end 

end 

probarlo y quiero saber si usted tiene cualquier problema con él, yo también lo publica como un problema a will_paginate repositorio, si todo el mundo confirma que funciona correctamente lo bifurcaré y lo comprometeré con la biblioteca. https://github.com/mislav/will_paginate/issues/351

Cuestiones relacionadas