2016-02-18 1 views
0

J'indexe actuellement les requêtes de recherche à l'aide de la gemme searchkick. Il convient également de noter que je suis à la recherche à travers deux modèles, Artists et Albums. Dans mon search_controller j'ai 3 variables d'instance, tout d'abord être @results pour retourner tous les résultats à travers les deux modèles pour mon autocomplete (utilisé ailleurs):Collecte des résultats de recherche à partir d'une requête multimodèle

@results = Artist.search(params[:query], index_name: [Artist.searchkick_index.name, Album.searchkick_index.name], fields: [{ name: :word_start }], limit: 10) 

Ensuite, il y a mes @artists/@albums variables d'instance.

@artists = @results.select { |result| result.class.name == "Artist" } 
@albums = @results.select { |result| result.class.name == "Album" } 

Je divisé ces résultats afin que, à mon avis d'index que je peux les artistes et les albums du groupe comme autant:

<h1>Search Results</h1> 

<div class="artist-results"> 
    <h2>Artists</h2> 

    <% @artists.each do |artist| %> 
    <%= link_to artist.name, artist_path(artist) %> 
    <% end %> 
</div> 

<div class="album-results"> 
    <h2>Albums</h2> 

    <% @albums.each do |album| %> 
    <%= link_to album.name, album_path(album) %> 
    <% end %> 
</div> 

L'une des principales préoccupations que j'ai avec mon code de contrôleur de recherche est que je suis effectuer 2 énumération presque identiques. Je peux me tromper mais quelque chose me dit que je ne devrais pas faire ça. Existe-t-il une solution plus performante à ce que je fais? Suis-je sur la bonne voie avec ça?

Code contrôleur complet

class SearchController < ApplicationController 
    before_filter :set_results 

    def index 
    end 

    def autocomplete 
    render json: @results 
    end 

    private 
    def set_results 
     @results = Artist.search(params[:query], index_name: [Artist.searchkick_index.name, Album.searchkick_index.name], fields: [{ name: :word_start }], limit: 10) 
     @artists = @results.select { |result| result.class.name == "Artist" } 
     @albums = @results.select { |result| result.class.name == "Album" } 
    end 
end 

Répondre

1

Je ne sais pas qu'il est plus performant. Mais vous pouvez utiliser group by.

results = Artist.search(params[:query], index_name: [Artist.searchkick_index.name, Album.searchkick_index.name], fields: [{ name: :word_start }], limit: 10) 
@grouped_results = results.group_by{|x| x.class.name } 

Puis

<h1>Search Results</h1> 

<% @grouped_results.each do |class_name, results| %> 
    <div class="<%= class_name.downcase %>-results"> 
    <h2><%= class_name.pluralize %></h2> 

    <% results.each do |result| %> 
     <%= link_to result %> 
    <% end %>  
    </div> 
<% end %> 
+0

Merci. Je pense qu'il vous manque une double citation à la fin de la déclaration de classe. –

+0

Je suis, bon endroit. –

+0

Pas de problème. Trouvé une erreur de ma part. J'ai oublié d'ajouter le premier paramètre à mon 'link_to'. Donc, fondamentalement '<% ​​= link_to result%>' aurait dû se lire comme '<% = link_to result.name, result%>'. C'est mauvais pour ne pas l'écrire complètement dans ma question originale. –