class FortyFacets::FacetSearch

Inherit this class to create a custom search for your model

class MovieSearch < FortyFacets::FacetSearch
  model 'Movie'

  text :title
  scope :someScope, name: 'Only very special'
  range :price
  facet :genre, name: 'Genre'
  facet :year, name: 'Releaseyear', order: :year
  facet :studio, name: 'Studio', order: :name

  orders 'Title' => :title,
         'price, cheap first' => "price asc",
         'price, expensive first' => {price: :desc, title: :desc},
         'Title, reverse' => {order: "title desc", default: true}
  custom :for_manual_handling

end

Attributes

filters[R]
orders[R]

Public Class Methods

custom(path, opts = {}) click to toggle source
# File lib/forty_facets/facet_search.rb, line 37
def custom(path, opts = {})
  definitions << CustomFilterDefinition.new(self, path, opts)
end
definitions() click to toggle source
# File lib/forty_facets/facet_search.rb, line 61
def definitions
  @definitions ||= []
end
facet(path, opts = {}) click to toggle source
# File lib/forty_facets/facet_search.rb, line 49
def facet(path, opts = {})
  definitions << FacetFilterDefinition.new(self, path, opts)
end
model(model) click to toggle source
# File lib/forty_facets/facet_search.rb, line 25
def model(model)
  if model.is_a? Class
    @root_class = model
  else
    @root_class = Kernel.const_get(model)
  end
end
new(request_params = {}, root = nil) click to toggle source
# File lib/forty_facets/facet_search.rb, line 86
def initialize(request_params = {}, root = nil)
  params = request_to_search_params(request_params)
  @filters = self.class.definitions.inject([]) do |filters, definition|
    filters << definition.build_filter(self, params[definition.request_param])
  end

  @orders = self.class.order_definitions.inject([]) do |orders, definition|
    orders << definition.build(self, params[:order])
  end

  unless @orders.find(&:active)
    default_order = @orders.find {|o| o.definition.default}
    default_order.active = true if default_order
  end

  @root = root
end
new_unwrapped(params, root) click to toggle source
# File lib/forty_facets/facet_search.rb, line 104
def self.new_unwrapped(params, root)
  self.new({request_param_name => params}, root)
end
order_definitions() click to toggle source
# File lib/forty_facets/facet_search.rb, line 81
def order_definitions
  @order_definitions ||= []
end
orders(name_and_order_options) click to toggle source
# File lib/forty_facets/facet_search.rb, line 57
def orders(name_and_order_options)
  @order_definitions = name_and_order_options.to_a.inject([]) {|ods, no| ods << OrderDefinition.new(no.first, no.last)}
end
range(path, opts = {}) click to toggle source
# File lib/forty_facets/facet_search.rb, line 45
def range(path, opts = {})
  definitions << RangeFilterDefinition.new(self, path, opts)
end
request_param(name) click to toggle source
# File lib/forty_facets/facet_search.rb, line 73
def request_param(name)
  @request_param_name = name
end
request_param_name() click to toggle source
# File lib/forty_facets/facet_search.rb, line 77
def request_param_name
  @request_param_name ||= 'search'
end
root_class() click to toggle source
# File lib/forty_facets/facet_search.rb, line 65
def root_class
  @root_class || raise('No model class given')
end
root_scope() click to toggle source
# File lib/forty_facets/facet_search.rb, line 69
def root_scope
  root_class.all
end
scope(path, opts = {}) click to toggle source
# File lib/forty_facets/facet_search.rb, line 41
def scope(path, opts = {})
  definitions << ScopeFilterDefinition.new(self, path, opts)
end
sql_facet(queries, opts = {}) click to toggle source
# File lib/forty_facets/facet_search.rb, line 53
def sql_facet(queries, opts = {})
  definitions << SqlFacetFilterDefinition.new(self, queries, opts)
end
text(path, opts = {}) click to toggle source
# File lib/forty_facets/facet_search.rb, line 33
def text(path, opts = {})
  definitions << TextFilterDefinition.new(self, path, opts)
end

Public Instance Methods

change_root(new_root) click to toggle source
# File lib/forty_facets/facet_search.rb, line 163
def change_root new_root
  @root = new_root
end
filter(filter_name) click to toggle source
# File lib/forty_facets/facet_search.rb, line 108
def filter(filter_name)
  filter = @filters.find { |f| f.definition.path == [filter_name].flatten }
  raise "Unknown filter #{filter_name}" unless filter
  filter
end
order() click to toggle source
# File lib/forty_facets/facet_search.rb, line 114
def order
  @orders.find(&:active)
end
params() click to toggle source
# File lib/forty_facets/facet_search.rb, line 141
def params
  params = @filters.inject({}) do |sum, filter|
    sum[filter.definition.request_param] = filter.value.dup unless filter.empty?
    sum
  end
  params[:order] = order.definition.request_value if order && order != @orders.find {|o| o.definition.default}
  params
end
path() click to toggle source
# File lib/forty_facets/facet_search.rb, line 150
def path
  return nil if wrapped_params.empty?
  '?' + wrapped_params.to_param
end
result(skip_ordering: false) click to toggle source
# File lib/forty_facets/facet_search.rb, line 118
def result(skip_ordering: false)
  query = @filters.reject(&:empty?).inject(root) do |previous, filter|
    # p 'PREVIOS'
    # p previous
    # p 'FILTER'
    # p filter
    # p '..........'
    filter.build_scope.call(previous)
  end
  
  if order && !skip_ordering
    query = order.apply(query)
  else
    query = query.distinct
  end
  query
end
root() click to toggle source
# File lib/forty_facets/facet_search.rb, line 159
def root
  @root || self.class.root_scope
end
unfiltered?() click to toggle source
# File lib/forty_facets/facet_search.rb, line 155
def unfiltered?
  @filters.reject(&:empty?).empty?
end
wrapped_params() click to toggle source
# File lib/forty_facets/facet_search.rb, line 136
def wrapped_params
  return {} if params.empty?
  { self.class.request_param_name => params }
end

Private Instance Methods

request_to_search_params(request_params) click to toggle source
# File lib/forty_facets/facet_search.rb, line 169
def request_to_search_params(request_params)
  if request_params && request_params[self.class.request_param_name]
    should_be_hash = request_params[self.class.request_param_name]
    if should_be_hash.respond_to?(:permit!)
      should_be_hash = should_be_hash.permit!.to_h
    end
    if should_be_hash.is_a? Hash
      should_be_hash
    else
      {}
    end
  else
    {}
  end
end