6

Después de bastante buscar, aún estoy un poco perdido. Hay algunas otras preguntas similares que tratan sobre paginar múltiples modelos, pero no tienen respuesta o pagan por cada modelo por separado.cómo paginar registros de múltiples modelos? (¿Necesito una unión polimórfica?)

Necesito paginar todos los registros de una cuenta a la vez.

class Account 
    :has_many :emails 
    :has_many :tasks 
    :has_many :notes 
end 

lo tanto, me gustaría encontrar los 30 más recientes "cosas" no importa lo que son. ¿Es esto posible con las soluciones de paginación actuales?

¿Te gusta usar alguna combinación de carga ansiosa y Kaminari o will_paginate?


O, ¿debería configurar primero una unión polimórfica de todas estas cosas, llamada Elementos. A continuación, pagine los últimos 30 elementos, luego haga una búsqueda de los registros asociados de esos elementos.

Y si es así, no estoy muy seguro de cómo debería ser ese código. ¿Alguna sugerencia?


¿Qué camino es mejor? (o incluso posible)

Rails 3.1, Ruby 1.9.2, aplicación no en producción.

+0

Use will_paginate, th es de ayuda: http://stackoverflow.com/questions/1465949/how-to-use-will-paginate-with-a-nested-resource-in-rails –

+0

Gracias. Pero, eso no es lo que estoy buscando. – GoodGets

+0

Piense que "la búsqueda a través de un conjunto de filas de datos" en lugar de buscar varias filas de una tabla de base de datos puede ayudar. No debería importar de cuántos modelos provienen los datos. También puede consultar kaminiri para ver si satisface mejor sus necesidades. –

Respuesta

1

Buena pregunta ... no estoy seguro de una solución "bueno", pero se puede hacer una hacky en rubí:

Se necesitaría a buscar primero el más reciente el 30 de cada tipo de "cosa", y ponerlos en una matriz, indexada por created_at, a continuación, ordenar que la matriz por created_at y tomar la parte superior 30.

un totalmente no refactorizado inicio podría ser algo como:

emails = Account.emails.all(:limit => 30, :order => :created_at) 
tasks = Account.tasks.all(:limit => 30, :order => :created_at) 
notes = Account.notes.all(:limit => 30, :order => :created_at) 
thing_array = (emails + tasks + notes).map {|thing| [thing.created_at, thing] } 
# sort by the first item of each array (== the date) 
thing_array_sorted = thing_array.sort_by {|a,b| a[0] <=> b[0] } 
# then just grab the top thirty 
things_to_show = thing_array_sorted.slice(0,30) 

Nota : no probado, podría estar lleno de errores ...;)

+0

Gracias por su respuesta. Sin embargo, eso sería demasiado terrible, teniendo que buscar 60 registros extra cada vez. Luego tener que hacer un seguimiento de cuántos de cada uno se presentaron. Además, you things_array podría refactorizarse a algo como: '(correos electrónicos + tareas + notas) .sort_by (&: updated_at) .take (30)' – GoodGets

+0

necesita revertir para obtener la más reciente: '(correos electrónicos + tareas + notas) .sort_by (&: updated_at) .reverse.take (30) ' – GoodGets

+0

Sí, definitivamente no es tan bueno ... como dije, solo una solución hacky :) –

2

con will_paginate:

@records = #do your work and fetch array of records you want to paginate (various types) 

luego haga lo siguiente:

current_page = params[:page] || 1 
per_page = 10 
@records = WillPaginate::Collection.create(current_page, per_page, records.size) do |pager| 
pager.replace(@records) 
end 

continuación, en su opinión:

<%=will_paginate @records%> 
0
emails = account.emails 
tasks = account.tasks 
notes = account.notes 

@records = [emails + tasks + notes].flatten.sort_by(&:updated_at).reverse 

@records = WillPaginate::Collection.create(params[:page] || 1, 30, @records.size) do |pager| 
    pager.replace(@records) 
end 

Eso es todo ... :)

Cuestiones relacionadas