Class: Supernova::Criteria

Inherits:
Object
  • Object
show all
Defined in:
lib/supernova/criteria.rb

Direct Known Subclasses

SolrCriteria

Constant Summary collapse

DEFAULT_PER_PAGE =
25
FIRST_PAGE =
1

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(clazz = nil) ⇒ Criteria

Returns a new instance of Criteria.



22
23
24
25
26
# File 'lib/supernova/criteria.rb', line 22

def initialize(clazz = nil)
  self.clazz = clazz
  self.filters = {}
  self.search_options = {}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args, &block) ⇒ Object



190
191
192
193
194
195
196
197
198
199
# File 'lib/supernova/criteria.rb', line 190

def method_missing(*args, &block)
  if Supernova::Collection.instance_methods.include?(args.first.to_s)
    populate
    @results.send(*args, &block)
  elsif self.named_scope_defined?(args.first)
    self.merge(self.search_options[:named_scope_class].send(*args)) # merge named scope and current criteria
  else
    super
  end
end

Instance Attribute Details

#clazzObject

Returns the value of attribute clazz.



5
6
7
# File 'lib/supernova/criteria.rb', line 5

def clazz
  @clazz
end

#filtersObject

Returns the value of attribute filters.



5
6
7
# File 'lib/supernova/criteria.rb', line 5

def filters
  @filters
end

#resultsObject

Returns the value of attribute results.



5
6
7
# File 'lib/supernova/criteria.rb', line 5

def results
  @results
end

#search_optionsObject

Returns the value of attribute search_options.



5
6
7
# File 'lib/supernova/criteria.rb', line 5

def search_options
  @search_options
end

Class Method Details

.method_missing(*args) ⇒ Object



8
9
10
11
12
13
14
15
# File 'lib/supernova/criteria.rb', line 8

def method_missing(*args)
  scope = self.new
  if scope.respond_to?(args.first)
    scope.send(*args)
  else
    super
  end
end

.select(*args) ⇒ Object



17
18
19
# File 'lib/supernova/criteria.rb', line 17

def select(*args)
  self.new.send(:select, *args)
end

Instance Method Details

#attribute_mapping(mapping) ⇒ Object



32
33
34
# File 'lib/supernova/criteria.rb', line 32

def attribute_mapping(mapping)
  merge_search_options :attribute_mapping, mapping
end

#conditions(filters) ⇒ Object



77
78
79
# File 'lib/supernova/criteria.rb', line 77

def conditions(filters)
  merge_filters :conditions, filters
end

#current_pageObject



164
165
166
# File 'lib/supernova/criteria.rb', line 164

def current_page
  pagination_attribute_when_greater_zero(:page) || 1
end

#executeObject



160
161
162
# File 'lib/supernova/criteria.rb', line 160

def execute
  implement_in_subclass
end

#facet_fields(*fields) ⇒ Object



73
74
75
# File 'lib/supernova/criteria.rb', line 73

def facet_fields(*fields)
  merge_filters_array :facets, fields
end

#for_classes(clazzes) ⇒ Object



28
29
30
# File 'lib/supernova/criteria.rb', line 28

def for_classes(clazzes)
  merge_filters :classes, [clazzes].flatten
end

#group_by(group_option) ⇒ Object



44
45
46
# File 'lib/supernova/criteria.rb', line 44

def group_by(group_option)
  merge_search_options :group_by, group_option
end

#implement_in_subclassObject



176
177
178
# File 'lib/supernova/criteria.rb', line 176

def implement_in_subclass
  raise "implement in subclass"
end

#limit(limit_option) ⇒ Object



40
41
42
# File 'lib/supernova/criteria.rb', line 40

def limit(limit_option)
  merge_search_options :limit, limit_option
end

#merge(other_criteria) ⇒ Object



180
181
182
183
184
185
186
187
188
# File 'lib/supernova/criteria.rb', line 180

def merge(other_criteria)
  other_criteria.filters.each do |key, value|
    self.merge_filters(key, value)
  end
  other_criteria.search_options.each do |key, value|
    self.merge_search_options(key, value)
  end
  self
end

#merge_filters(key, value) ⇒ Object



113
114
115
# File 'lib/supernova/criteria.rb', line 113

def merge_filters(key, value)
  merge_filters_or_search_options(self.filters, key, value)
end

#merge_filters_array(key, fields) ⇒ Object



117
118
119
120
121
122
123
# File 'lib/supernova/criteria.rb', line 117

def merge_filters_array(key, fields)
  self.search_options[key] ||= Array.new
  fields.flatten.each do |field|
    self.search_options[key] << field if !self.search_options[key].include?(field)
  end
  self
end

#merge_filters_or_search_options(reference, key, value) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/supernova/criteria.rb', line 129

def merge_filters_or_search_options(reference, key, value)
  if value.is_a?(Hash)
    reference[key] ||= Hash.new
    reference[key].merge!(value)
  elsif key == :select
    reference[key] ||= Array.new
    reference[key] += (value || [])
  else
    reference[key] = value
  end
  self
end

#merge_search_options(key, value) ⇒ Object



125
126
127
# File 'lib/supernova/criteria.rb', line 125

def merge_search_options(key, value)
  merge_filters_or_search_options(self.search_options, key, value)
end

#named_scope_class(clazz) ⇒ Object



201
202
203
# File 'lib/supernova/criteria.rb', line 201

def named_scope_class(clazz)
  merge_search_options :named_scope_class, clazz
end

#named_scope_defined?(name) ⇒ Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/supernova/criteria.rb', line 205

def named_scope_defined?(name)
  self.search_options[:named_scope_class] && self.search_options[:named_scope_class].respond_to?(:defined_named_search_scopes) && self.search_options[:named_scope_class].defined_named_search_scopes.respond_to?(:include?) && self.search_options[:named_scope_class].defined_named_search_scopes.include?(name)
end

#near(*coordinates) ⇒ Object



85
86
87
# File 'lib/supernova/criteria.rb', line 85

def near(*coordinates)
  merge_search_options :geo_center, normalize_coordinates(*coordinates)
end

#normalize_coordinates(*args) ⇒ Object



97
98
99
100
101
102
103
104
# File 'lib/supernova/criteria.rb', line 97

def normalize_coordinates(*args)
  flattened = args.flatten
  if (lat = read_first_attribute(flattened.first, :lat, :latitude)) && (lng = read_first_attribute(flattened.first, :lng, :lon, :longitude))
    { :lat => lat.to_f, :lng => lng.to_f }
  elsif flattened.length == 2
    { :lat => flattened.first.to_f, :lng => flattened.at(1).to_f }
  end
end

#options(options_hash) ⇒ Object



93
94
95
# File 'lib/supernova/criteria.rb', line 93

def options(options_hash)
  merge_search_options :custom_options, options_hash
end

#order(order_option) ⇒ Object



36
37
38
# File 'lib/supernova/criteria.rb', line 36

def order(order_option)
  merge_search_options :order, order_option
end

#paginate(pagination_options) ⇒ Object



81
82
83
# File 'lib/supernova/criteria.rb', line 81

def paginate(pagination_options)
  merge_search_options :pagination, pagination_options
end

#pagination_attribute_when_greater_zero(attribute) ⇒ Object



172
173
174
# File 'lib/supernova/criteria.rb', line 172

def pagination_attribute_when_greater_zero(attribute)
  self.search_options[:pagination][attribute] if self.search_options[:pagination] && self.search_options[:pagination][attribute].to_i > 0
end

#per_pageObject



168
169
170
# File 'lib/supernova/criteria.rb', line 168

def per_page
  pagination_attribute_when_greater_zero(:per_page) || DEFAULT_PER_PAGE
end

#populateObject



146
147
148
149
# File 'lib/supernova/criteria.rb', line 146

def populate
  @results = execute if !populated?
  self
end

#populated?Boolean

Returns:

  • (Boolean)


156
157
158
# File 'lib/supernova/criteria.rb', line 156

def populated?
  instance_variables.include?("@results")
end

#read_first_attribute(object, *keys) ⇒ Object



106
107
108
109
110
111
# File 'lib/supernova/criteria.rb', line 106

def read_first_attribute(object, *keys)
  keys.each do |key|
    return object.send(key) if object.respond_to?(key)
  end
  nil
end

#search(*terms) ⇒ Object



48
49
50
# File 'lib/supernova/criteria.rb', line 48

def search(*terms)
  merge_filters_array :search, terms
end

#select(*fields) ⇒ Object



69
70
71
# File 'lib/supernova/criteria.rb', line 69

def select(*fields)
  merge_filters_array :select, fields
end

#to_aObject



151
152
153
154
# File 'lib/supernova/criteria.rb', line 151

def to_a
  populate
  results
end

#to_parametersObject



142
143
144
# File 'lib/supernova/criteria.rb', line 142

def to_parameters
  implement_in_subclass
end

#where(*args) ⇒ Object



56
57
58
# File 'lib/supernova/criteria.rb', line 56

def where(*args)
  with(*args)
end

#with(filters) ⇒ Object



52
53
54
# File 'lib/supernova/criteria.rb', line 52

def with(filters)
  merge_filters :with, filters
end

#within(distance) ⇒ Object



89
90
91
# File 'lib/supernova/criteria.rb', line 89

def within(distance)
  merge_search_options :geo_distance, distance
end

#without(filters) ⇒ Object



60
61
62
63
64
65
66
67
# File 'lib/supernova/criteria.rb', line 60

def without(filters)
  self.filters[:without] ||= Hash.new
  filters.each do |key, value|
    self.filters[:without][key] ||= Array.new
    self.filters[:without][key] << value if !self.filters[:without][key].include?(value)
  end
  self
end