4

Обновлено 6/29/12Выберите несколько граней или фильтровать данные одновременно

мне удалось настроить поиск и боковую планку для фильтрации результатов поиска с использованием SunSpot и акт-как-taggable с Rails , Я следовал этому руководству here , но я все еще не могу выбрать mutliple filter's сразу. Когда я выбираю фильтр, имена других подкатегорий все же исчезают. Что мне не хватает?

Мой первоначальный вопрос был такой:

Я не совсем уверен, как выбрать несколько аспектов одновременно фильтрации данных . Таким образом, у меня есть несколько подкатегорий, например, (походы, катание на лыжах, скалолазание, и т. Д.). Я хочу иметь возможность выбирать походы и восхождение одновременно , поэтому приведенные данные - это только объекты похода и восхождения. Right сейчас я выбираю один (скажем, поход), и все остальные варианты исчезают. Может кто-нибудь объяснить?

Ниже мой код:

передач Контроллер

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 

** Снасти 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> 

передач Модель

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 
+0

Должен ли я думать об этом по-другому? Я новичок, поэтому, если я пытаюсь сделать что-то с Sunspot, это должно быть сделано другим способом, дайте мне знать ... Спасибо за помощь! – DaveG

ответ

3

Похоже, вам необходимо воспользоваться опцией :exclude для вашего гравюрного поиска.

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 

Так что я сделал выше, создать exclusions массив для хранения набора фильтров. Метод with() возвращает объект фильтра, поэтому мы фиксируем все фильтры в массиве exclusions. Мы делаем compact!, чтобы удалить ненулевые объекты из массива, и если он пуст, мы делаем его nil (это связано с ограничениями параметра :exclude, если вы передадите ему пустой массив, это не сработает правильно). Затем мы получаем facet на том же :sub_category_name термине, за исключением фильтров, а также даем ему имя. Этот facet предоставит вам все категории фасетов, исключая выбранные.

Тогда, на ваш взгляд, когда вы показываете параметры фасета, вы используете фасет с именем :all_categories.

@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 
+0

Vanhowen, благодарю вас за ответ. Долгожданный :) Я скорректировал свой новый код, чтобы отразить ваш ответ. Сейчас, когда я выбираю одну подкатегорию, все они становятся избранными (я знаю, что это связано с моими изменениями). Я попытался реализовать ваш код выше, но когда я выбрал одну подкатегорию, а затем вторую, все результаты исчезнут. – DaveG

+1

Похоже, у нас есть две проблемы: 1. Когда вы выбираете одну подкатегорию, все они становятся выбранными. 2.Когда вы выбираете одну подкатегорию, результаты фильтруются правильно (даже если выбраны все категории). Но когда вы выбираете другую подкатегорию, все результаты исчезают. Чтобы исправить это, я передам массив фильтров подкатегорий из вашего представления в ваш метод поиска. Затем используйте массив фильтров в вашем поиске (так же, как работает цикл params [: tag] .each). На ваш взгляд, вам нужно проверить, существует ли текущее значение row.value в массиве фильтров. Имеют смысл? – vanhowen

+0

Да, вы правы, есть 2 проблемы, перечисленные выше. Спасибо за ответ. Я новый программист, я не уверен, как собрать это вместе, не сделав ничего подобного раньше (передайте массив из представления в метод, а затем используя массив в поиске). Вы могли бы добавить пример кода? – DaveG