简体   繁体   中英

Rails 5 Search filters multiple choice

I am trying to incorporate search filters on my search results page. After a user searches and the result are showcased on the search.html.erb I want them to use filters. The filters would be derived from the search results itself.

In other words I want to replicate what car gurus do. You search using make, model, price and then the filters would give you options for faceted search depending upon the search vehicle trim, transmission etc.

I tried single filter links like:

<%= addfilters "transmission", "Automatic" %>

and defining helper method like

def addfilters(column, title)
      link_to title, params.permit(:NewUsed, :category, :subcategory, :minprice, :maxprice, :location, :radius).merge({:"#{column}" => "Automatic"})
end

But how can I:

  1. Use multiple select filters to fine tune search results I get from search form.
  2. Populate these filter options using the search results, persist the results and merge new multiple values for params.
  3. I want to get something like:

    汽车大师

I don't want to use external dependencies or gems like ransack or filterrific, I want to learn faceted search from scratch.

If needed, my Search form code is:

<div id="Make" class="tabcontent1">
            <section class="formclass">

              <!-- f.select :transmission, ['Automanual','Automatic','Automatic 4 Speed','Automatic 5 Speed','Automatic 6 Speed','CVT','Manual'] -->
                <h3 style = "color:#F00000; text-align: center;"><strong><%= @carcount %> CARS LISTED!</strong></h3>

                <hr>

                <h3 style = "color:#7C064D;"><span class="glyphicon glyphicon-search"></span> <strong>SEARCH CARS FOR SALE BY MAKE</strong></h3>
                <%= form_tag search_listings_path, method: :get, class: 'navbar-form navbar-center' do |f| %>

                <div class= "col-xs-12 col-sm-12 col-lg-12 col-md-12"> 
                    <%= select_tag :NewUsed, "<option>New</option><option>Used</option>".html_safe, style: "width: 100%; margin: 1% 0;" %>
                </div>

                <div class= "col-xs-6 col-sm-6 col-lg-6 col-md-6"> 
                    <%= select_tag :category, include_blank: true, style: "width: 100%; margin: 1% 0;" %>
                </div>

                <div class= "col-xs-6 col-sm-6 col-lg-6 col-md-6"> 
                    <%= select_tag :subcategory, include_blank: true, style: "width: 100%; margin: 1% 0;" %>
                </div>
                <!-- <div class= "col-xs-12 col-sm-12 col-lg-12 col-md-12">  -->
                    <div class= "col-xs-6 col-sm-6 col-lg-6 col-md-6"> 
                        <%= text_field_tag :minprice, nil, placeholder: 'Min Price', style: "width: 100%; margin: 1% 0;" %>
                    </div>
                    <div class= "col-xs-6 col-sm-6 col-lg-6 col-md-6"> 
                        <%= text_field_tag :maxprice, nil, placeholder: 'Max Price', style: "width: 100%; margin: 1% 0;" %>
                    </div>
                <!-- </div> -->
                <div class= "col-xs-6 col-sm-6 col-lg-6 col-md-6"> 
                    <%= text_field_tag :location, nil, placeholder: 'Near', style: "width: 100%; margin: 1% 0;" %>
                </div>
                <div class= "col-xs-6 col-sm-6 col-lg-6 col-md-6"> 
                    <%= text_field_tag :radius, nil, placeholder: 'Radius', style: "width: 100%; margin: 1% 0;" %>
                </div>


                <div class= "col-xs-12 col-sm-12 col-lg-12 col-md-12">              
                    <%= submit_tag 'Search', class: 'btn btn-danger', style: "width: 100%;" %>
                </div>
              <% end %>    
            </section>
      </div>

A module like this would work

module Filterable
  extend ActiveSupport::Concern

  module ClassMethods
    def filter(filtering_params)
      results = self.where(nil)
      filtering_params.each do |key, value|
        results = results.public_send(key, value) if value.present?
      end
      results
    end
  end
end


#Controller
def index
  @products = Product.filter(params.slice(:status, :location, :over_price, :under_price))
end

#class Car < ApplicationRecord
class Product < ApplicationRecord
  include Filterable

  scope :status, -> (status) { where status: status }
  scope :location, -> (location_id) { where location_id: location_id }
  scope :over_price, -> (price) { where "price > ?", price) }
  scope :under_price, -> (price) { where "price < ?", price) }

  #continue adding more scopes here
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM