Rails için güçlü Sunspot gem ile bir site arama arama uygulamak çalışıyorum. Bu, aynı anda birden çok farklı model arasında bir arama yapılmasını içerir. Yapmak istediğim şey, kullanıcının arama sonuçlarını her bir modele göre filtrelemesini veya varsayılan olarak tümünün aynı sayfada görüntülenen, birbiriyle uyumlu hale getirilmiş: destekleyici niteleyici tarafından izin vermesini sağlamak için kaplama özelliğini kullanmaktır. Başka bir Stackoverflow question (Sunspot documentation'dan 'Çoklu Tip' kodunun bir varyasyonu) 'dan çoklu model arama koduyla facebook kodunu Sunspot Railscast'dan birleştirmek bana işe yarayacağını düşündüğüm bir çözüm verdi.Raylar Sunspot gem: Birden fazla model site çapında aramaları ile yönleri Kullanıyor
Birden çok yöntem araması başarılı olur, ancak yüzler daima sıfırlanır. Temel yaklaşımım, her modelde aynı ada göre sanal bir özellik sağlamaktır: search_class, yani bir dizeye işlenen modelin sınıf adıdır. Daha sonra bunu bir faset olarak kullanmayı denerim. Ancak, görünüm mantığında, facet'in (search.facet (: search_class) .rows) sonuçları her zaman döndürülmüş her örneğe sahip olsa bile @ search.results aynı sorguda birçok farklı model döndürdüğü zaman da dahil olmak üzere boş bir dizidir. mükemmel erişilebilir Instance.search_class özniteliği.
Rails 3.1.0 ve sunspot rayları kullanıyorum 1.2.1.
Bu faceting kodunun çalışması için ne yapmalıyım?
Denetleyici:
#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
Modeller:
#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
Görünüm:
#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>
Bunun için neden yüzler kullanıyorsunuz? Tüm olası sınıfların hepsinin sahip olduğu sonuç sayısı ile listelendiği bir seçim menüsü oluşturuyor musunuz? Ardından, arama yöntemini çağırdığınızda, arama için bağımsız değişken olarak ilgili sınıfı dinamik olarak çağırın. –
Verilerinizi yeniden indekslediniz mi? Verilerin güneş lekesi dosyalarında sınıf adı olup olmadığını kontrol ettiniz mi? – Sebastien