Reputation: 1203
UPDATED 6/29/12
I have managed to set up a search and a side bar for filtering results of a search using Sunspot and act-as-taggable with Rails. I was following this tutorial here but I still can't select mutliple filter's at once. When I select a filter the other sub-category names still disappear. What am I missing?
My Original Question was this:
I'm not quite sure how to select multiple facets at once filtering the data. So I have multiple sub categories i.e.(hiking, skiing, climbing, etc.) I want to be able to select hiking and climbing simultaneously so the data shown is only those objects of hiking and climbing. Right now I select one (let's say hiking) and all the other options disappear. Can someone explain?
Below is my code:
Gear Controller
def index
@search = Gear.solr_search do
exclusions = []
fulltext params[:search]
exclusions << with(:sub_category_name, params[:name]) if params[:name].present?
exclusions.compact!
exclusions = nil if exclusions.empty?
facet :sub_category_name
facet :sub_category_name, :exclude => exclusions, :name => :all_categories
paginate(page: params[:page], :per_page => 15)
end
@gears = @search.results
end
** Gear Index View**
<div class="gears_container">
<div class="side_bar_search">
<%= form_tag gears_path, :method => :get do %>
<p>
<%= text_field_tag :keywords, params[:keywords] , class: 'gearsearchbar' %> <%= submit_tag "Search", :name => nil, class: 'btn btn-inverse gearsearchbutton' %>
</p>
<% end %>
<div class="sidebar_section">Sub Category</div>
<ul>
<% for row in @search.facet(:all_categories).rows %>
<li class="sidebar_options">
<% if params[:name].present? %>
<strong><%= row.value %></strong>(<%= link_to "remove", :name => nil %>)
<% else %>
<%= link_to row.value, :name => row.value %> (<%= row.count %>)
<% end %>
</li>
<% end %>
</ul>
</div>
<div c
<div class="search_results_gear">
<% @hits.each do |gear| %>
<%= render partial: 'gear', locals: {gear: gear} %>
<% end %>
<div style="clear:both"></div>
<%= will_paginate @hits, class: 'flickr_pagination' %>
</br>
</div>
</div>
Gear Model
class Gear < ActiveRecord::Base
attr_accessible :title, :size, :price, :sub_category_id, :user_id, :image, :image_a, :remote_image_url, :color, :year, :latefee, :cancellation, :minrental, :policy, :about, :address, :city, :state, :zip, :sub_category_name
belongs_to :user
belongs_to :sub_category
has_one :category, :through => :sub_category
has_many :comments, :dependent => :destroy
has_many :line_items
require 'carrierwave/orm/activerecord'
mount_uploader :image, GearpicUploader
mount_uploader :image_a, GearpicUploader
before_destroy :ensure_not_referenced_by_any_line_item
acts_as_taggable_on :tags
validates :title, presence: true
validates :size, presence: true
validates :price, presence: true
validates :sub_category_id, presence: true
validates :user_id, presence: true
searchable do
text :title, :size, :price, :year, :zip, :state, :city, :minrental, :about, :latefee, :color
text :user_firstname do
user.firstname
end
text :user_lastname do
user.lastname
end
# **Facet Section**
string :size, :price, :year, :zip, :state, :city, :minrental, :latefee, :color
string :sub_category_name , :multiple => true, :stored => true do
sub_category.name
end
string :category_name do
category.name
end
end
private
def ensure_not_referenced_by_any_line_item
if line_items.empty?
return true
else
errors.add(:base, 'Line Items present')
return false
end
end
end
Upvotes: 4
Views: 1444
Reputation: 153
It looks like you need to take advantage of the :exclude
option for your faceted search.
def index
@search = Gear.search do
exclusions = []
# tags, AND'd
if params[:tag].present?
all_of do
params[:tag].each do |tag|
exclusions << with(:sub_category_name, tag)
end
end
end
exclusions.compact!
exclusions = nil if exclusions.empty?
facet :sub_category_name
facet :sub_category_name, :exclude => exclusions, :name => :all_categories
paginate(page: params[:page])
end
@hits = @search.results
end
So what I've done above, is create an exclusions
array to hold the collection of filters. The with()
method returns a filter object, so we capture all the filters in the exclusions
array. We do the compact!
to remove nil objects from the array, and if it's empty, we make it nil
(this is due to the limitations of the :exclude
option, if you pass it an empty array, it will not work correctly). We then facet
on the same :sub_category_name
term, excluding the filters, and also give it a name. This facet
will give you all the facet categories excluding the selected ones.
Then in your view, when you display the facet options, you use the named :all_categories
facet.
@search.facet(:all_categories).rows.each_with_index do |facet, index|
# This just outputs all the facets, you can add the logic in.
<li><%= facet.value %> (<%= facet.count %>)</li>
end
Upvotes: 3