I'm currently indexing search queries using the searchkick gem. It should also be noted that I'm searching across two models, Artists
and Albums
. In my search_controller
I have 3 instance variables, first being @results
for returning all results across the two models for my autocomplete
(used elsewhere):
@results = Artist.search(params[:query], index_name: [Artist.searchkick_index.name, Album.searchkick_index.name], fields: [{ name: :word_start }], limit: 10)
Then there are my @artists/@albums
instance variables.
@artists = @results.select { |result| result.class.name == "Artist" }
@albums = @results.select { |result| result.class.name == "Album" }
I split these results up so that I can group artists and albums in my index view as so:
<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>
The one main concern I have with my search controller code is that I'm performing 2 almost identical enumerables. I could be wrong but something tells me that I shouldn't do this. Is there a more performant solution to what I'm doing? Am I on the right track with this?
Complete Controller Code
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
Not sure it's more performant. But you could Use 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 }
Then
<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 %>