Sto cercando di implementare una ricerca sul tutto il sito attraverso la potente gemma Sunspot per Rails. Ciò comporta una ricerca su più modelli molto diversi contemporaneamente. Ciò che VOGLIO fare è utilizzare la funzione di sfaccettatura per consentire all'utente di filtrare i risultati della ricerca su ciascun modello o, per impostazione predefinita, visualizzare tutti sulla stessa pagina, intercalati l'uno con l'altro ordinati dal qualificatore boost. Combinando il codice sfaccettato dal codice Sunspot Railscast con il codice di ricerca di più modelli da un altro Stackoverflow question (una variazione sul codice "Tipo multiplo" dal numero Sunspot documentation) mi ha fornito una soluzione che avrei pensato potesse funzionare, ma non lo è.Rails Sunspot gem: sfaccettature di utilizzo con più ricerche su tutto il sito modello
La ricerca di più metodi ha esito positivo, ma le faccette risultano sempre nulle. Il mio approccio di base è quello di fornire un attributo virtuale su ogni modello con lo stesso nome,: search_class, che è solo il nome della classe del modello reso in una stringa. Allora provo a usarlo come sfaccettatura. Tuttavia, nella logica della vista i risultati del facet (@ search.facet (: search_class) .rows) sono sempre un array vuoto, incluso quando @ search.results restituisce molti modelli diversi nella stessa query, nonostante ogni istanza restituita abbia un Attributo Instance.search_class perfettamente accessibile.
Utilizzo Rails 3.1.0 e sunspot-rails 1.2.1.
Cosa devo fare per far funzionare questo codice di sfaccettatura?
controllore:
#searches_controller.rb
class SearchesController < ApplicationController
def show
@search = search(params[:q])
@results = @search.results
end
protected
def search(q)
Sunspot.search Foo, Bar, CarlSagan do
keywords q
#provide faceting for "search class", a field representing a pretty version of the model name
facet(:search_class)
with(:search_class, params[:class]) if params[:class].present?
paginate(:page => params[:page], :per_page => 30)
end
end
end
Modelli:
#Foo.rb
class Foo < ActiveRecord::Base
searchable do
text :full_name, :boost => 5
text :about, :boost => 2
#string for faceting
string :search_class
end
#get model name, and, if 2+ words, make pretty
def search_class
self.class.name#.underscore.humanize.split(" ").each{|word| word.capitalize!}.join(" ")
end
end
#Bar.rb
class Bar < ActiveRecord::Base
searchable do
text :full_name, :boost => 5
text :about, :boost => 2
#string for faceting
string :search_class
end
#get model name, and, if 2+ words, make pretty
def search_class
self.class.name.underscore.humanize.split(" ").each{|word| word.capitalize!}.join(" ")
end
end
#CarlSagan.rb
class CarlSagan < ActiveRecord::Base
searchable do
text :full_name, :boost => 5
text :about, :boost => 2
#string for faceting
string :search_class
end
#get model name, and, if 2+ words, make pretty
def search_class
self.class.name#.underscore.humanize.split(" ").each{|word| word.capitalize!}.join(" ")
end
end
Vista:
#searches/show.html.erb
<div id="search_results">
<% if @results.present? %> # If results exist, display them
# If Railscasts-style facets are found, display and allow for filtering through params[:class]
<% if @search.facet(:search_class).rows.count > 0 %>
<div id="search_facets">
<h3>Found:</h3>
<ul>
<% for row in @search.facet(:search_class).rows %>
<li>
<% if params[:class].blank? %>
<%= row.count %> <%= link_to row.value, :class => row.value %>
<% else %>
<strong><%= row.value %></strong> (<%= link_to "remove", :class => nil %>)
<% end %>
</li>
<% end %>
</ul>
</div>
<% end %>
<% @results.each do |s| %>
<div id="search_result">
<% if s.class.name=="Foo"%>
<h5>Foo</h5>
<p><%= link_to s.name, foo_path(s) %></p>
<% elsif s.class.name=="Bar"%>
<h5>Bar</h5>
<p><%= link_to s.name, bar_path(s) %></p>
<% elsif s.class.name=="CarlSagan"%>
<h5>I LOVE YOU CARL SAGAN!</h5>
<p><%= link_to s.name, carl_sagan_path(s.user) %></p>
<% end %>
</div>
<% end %>
<% else %>
<p>Your search returned no results.</p>
<% end %>
</div>
Perché dovresti usare le sfaccettature per questo? Non puoi semplicemente creare un menu di scelta in cui sono elencate tutte le classi possibili con il numero di risultati che tutti hanno? Quindi quando chiamate il metodo di ricerca, chiamate dinamicamente la classe correlata come argomento per la ricerca? –
Hai reindicizzato i tuoi dati? E hai controllato se i dati avevano il nome della classe nei file di sunspot? – Sebastien