2011-06-10 23 views
19

Estoy creando una página de búsqueda que hará una amplia búsqueda de usuarios, publicaciones y comentarios. Actualmente tengo:Paginate Múltiples modelos en Kaminari

# POST /search 
def index 
    query = params[:query] 
    @users = User.search(query).page(params[:page]) 
    @posts = Post.search(query).page(params[:page]) 
    @comments = Comment.search(query).page(params[:page]) 

    respond_to do |format| 
    format.html 
    end 
end 

Sin embargo, yo estoy tratando de conseguir algo en el que todos los resultados se mezclan entre sí y luego paginado. ¿Cuáles son algunas de las estrategias para hacer búsquedas paginadas como esta? ¡Gracias!

Respuesta

1

Antes de pensar en una solución, es necesario primero definir exactamente lo que desea que el resultado final sea. Si desea mostrar unos pocos de cada tipo de registro en la página de resultados que puede modificar el enfoque informados y combinar los tres resultados paginados usando:

@results = @users + @posts + @comments 
@results.sort! { |a, b| a.score(query) > b.score(query) } 

Cada objeto tendrá que tener un método de instancia 'puntuación' eso lo dejará ordenar basado en la prioridad de consulta. Además, deberá modificar su vista para manejar la representación correcta de cada elemento y asegurarse de que se llame a la paginación en el modelo con más páginas.

Alternativamente, un método más robusto sería agregar un servicio de búsqueda de texto completo (como Index Tank, Web Solr, Thinking Sphinx). La tecnología para lo que está caliente para estos movimientos se mueve rápidamente, así que investigue un poco y encuentre uno que se adapte a sus necesidades. Ejemplo de sintaxis para esto sería algo así como:

User.multi_solr_search query, models: [Post, Comment] 
0

Puede combinar los resultados de la consulta y ejecutar la página en eso.

users = User.search(query) 
posts = Post.search(query) 
comments = Comment.search(query) 
@results = users + posts + comments 
@results.page(params[:page]) 
+4

Parte de los beneficios de joyas como '' kaminari' y paginate' es que utilizan el SQL '' Límite de las aguas y offset' cláusulas . ¡Si resuelves el problema de esta manera, perderás ese beneficio! –

+0

Ah, jou. Lo malo fue que sugerí la búsqueda de texto completo, ya que buscar con AR parece un feo truco. –

+0

@KevinSylvestre ¿Has encontrado una buena solución, aparte de mantener todos esos modelos en una sola mesa? ¡Me encanta verte aquí! – elsurudo

44

Desde esta confirmación: https://github.com/amatsuda/kaminari/commit/f9f529fb68ab89feea38773a4c625c1b14859128

Usted puede hacer lo siguiente

En su opinión se puede hacer esto:

<%= paginate @users, :remote => true, :param_name => "user_page" %> 
<%= paginate @posts, :remote => true, :param_name => "post_page" %> 
<%= paginate @comments, :remote => true, :param_name => "comment_#{some_post_id}_page" %> 

y luego en su controlador puede referirse a ellos de esta manera:

@users = User.search(query).page(params[:user_page]) 
@posts = Post.search(query).page(params[:post_page]) 
@comments = Comment.search(query).page(params[:comment_page]) 

y js.erb de su punto de vista es posible que tenga algo como:

$('#posts').html('<%= escape_javascript render(@posts) %>'); 
$('.table-pager').html('<%= escape_javascript(paginate(@posts, :remote => true).to_s) %>'); 
+1

Michael, gracias por la respuesta muy agradable, clara y concisa. Sería muy útil si pudiera expandir su respuesta con el javascript necesario para manejar esta situación. Soy un neófito de JavaScript y estoy luchando poderosamente para intentar que el ejemplo javascript del autor Kaminari funcione en varios modelos. –

+0

¡Gran información aquí! Me ayudó a resolver el problema que estaba teniendo. – matthewvb

+2

@Don para una solución simple y rápida sin javascript, simplemente elimine ": remote => true". – Eduardo

Cuestiones relacionadas