我試圖通過Rails的強大的黑子寶石來實現全站搜索。這涉及到一次搜索多個非常不同的模型。我想要做的是使用faceting功能來允許用戶在每個模型上過濾他們的搜索結果,或者默認情況下在同一頁面上查看所有內容,這些內容與由boost限定符排序的對方相互穿插。將來自Sunspot Railscast的分面代碼與來自另一個Stackoverflow question(來自Sunspot documentation的'多種類型'代碼的變體)的多模型搜索代碼相結合,給了我一個我認爲會起作用的解決方案,但卻沒有。Rails黑子寶石:使用多個模型全站搜索的方面
多重方法搜索成功,但小面總是變爲空。我的基本方法是爲每個模型提供一個相同名稱的虛擬屬性:search_class,它只是將模型的類名渲染爲字符串。然後我嘗試使用它作爲一個方面。然而,在視圖邏輯中,facet(@ search.facet(:search_class).rows)的結果始終是一個空數組,包括@ search.results在同一查詢中返回許多不同模型時,儘管每個返回的實例都有一個完全可訪問的Instance.search_class屬性。
我使用Rails 3.1.0和sunspot-rails 1.2.1。
我該怎麼做才能使這個代碼工作?
控制器:
#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
型號:
#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
檢視:
#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>
爲什麼你會爲此使用方面?你不能創建一個選擇菜單,其中列出了所有可能的類和所有結果的數量嗎?那麼當你調用搜索方法時,動態調用相關類作爲搜索的參數? –
您是否重新編制索引數據?你是否檢查數據是否在太陽黑子文件中有類名? – Sebastien