Class: FortyFacets::FacetSearch

Inherits:
Object
  • Object
show all
Defined in:
lib/forty_facets/facet_search.rb

Overview

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(request_params = {}, root = nil) ⇒ FacetSearch

Returns a new instance of FacetSearch.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# 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

Instance Attribute Details

#filtersObject (readonly)

Returns the value of attribute filters.



22
23
24
# File 'lib/forty_facets/facet_search.rb', line 22

def filters
  @filters
end

#ordersObject (readonly)

Returns the value of attribute orders.



22
23
24
# File 'lib/forty_facets/facet_search.rb', line 22

def orders
  @orders
end

Class Method Details

.custom(path, opts = {}) ⇒ Object



37
38
39
# File 'lib/forty_facets/facet_search.rb', line 37

def custom(path, opts = {})
  definitions << CustomFilterDefinition.new(self, path, opts)
end

.definitionsObject



61
62
63
# File 'lib/forty_facets/facet_search.rb', line 61

def definitions
  @definitions ||= []
end

.facet(path, opts = {}) ⇒ Object



49
50
51
# File 'lib/forty_facets/facet_search.rb', line 49

def facet(path, opts = {})
  definitions << FacetFilterDefinition.new(self, path, opts)
end

.model(model) ⇒ Object



25
26
27
28
29
30
31
# 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_unwrapped(params, root) ⇒ Object



104
105
106
# File 'lib/forty_facets/facet_search.rb', line 104

def self.new_unwrapped(params, root)
  self.new({request_param_name => params}, root)
end

.order_definitionsObject



81
82
83
# File 'lib/forty_facets/facet_search.rb', line 81

def order_definitions
  @order_definitions ||= []
end

.orders(name_and_order_options) ⇒ Object



57
58
59
# 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 = {}) ⇒ Object



45
46
47
# File 'lib/forty_facets/facet_search.rb', line 45

def range(path, opts = {})
  definitions << RangeFilterDefinition.new(self, path, opts)
end

.request_param(name) ⇒ Object



73
74
75
# File 'lib/forty_facets/facet_search.rb', line 73

def request_param(name)
  @request_param_name = name
end

.request_param_nameObject



77
78
79
# File 'lib/forty_facets/facet_search.rb', line 77

def request_param_name
  @request_param_name ||= 'search'
end

.root_classObject



65
66
67
# File 'lib/forty_facets/facet_search.rb', line 65

def root_class
  @root_class || raise('No model class given')
end

.root_scopeObject



69
70
71
# File 'lib/forty_facets/facet_search.rb', line 69

def root_scope
  root_class.all
end

.scope(path, opts = {}) ⇒ Object



41
42
43
# File 'lib/forty_facets/facet_search.rb', line 41

def scope(path, opts = {})
  definitions << ScopeFilterDefinition.new(self, path, opts)
end

.sql_facet(queries, opts = {}) ⇒ Object



53
54
55
# File 'lib/forty_facets/facet_search.rb', line 53

def sql_facet(queries, opts = {})
  definitions << SqlFacetFilterDefinition.new(self, queries, opts)
end

.text(path, opts = {}) ⇒ Object



33
34
35
# File 'lib/forty_facets/facet_search.rb', line 33

def text(path, opts = {})
  definitions << TextFilterDefinition.new(self, path, opts)
end

Instance Method Details

#change_root(new_root) ⇒ Object



163
164
165
# File 'lib/forty_facets/facet_search.rb', line 163

def change_root new_root
  @root = new_root
end

#filter(filter_name) ⇒ Object



108
109
110
111
112
# 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

#orderObject



114
115
116
# File 'lib/forty_facets/facet_search.rb', line 114

def order
  @orders.find(&:active)
end

#paramsObject



141
142
143
144
145
146
147
148
# 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

#pathObject



150
151
152
153
# 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) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# 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

#rootObject



159
160
161
# File 'lib/forty_facets/facet_search.rb', line 159

def root
  @root || self.class.root_scope
end

#unfiltered?Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/forty_facets/facet_search.rb', line 155

def unfiltered?
  @filters.reject(&:empty?).empty?
end

#wrapped_paramsObject



136
137
138
139
# File 'lib/forty_facets/facet_search.rb', line 136

def wrapped_params
  return {} if params.empty?
  { self.class.request_param_name => params }
end