Class: Supernova::Criteria
- Inherits:
-
Object
- Object
- Supernova::Criteria
show all
- Defined in:
- lib/supernova/criteria.rb
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.
34
35
36
37
38
39
|
# File 'lib/supernova/criteria.rb', line 34
def initialize(clazz = nil)
self.clazz = clazz
self.filters = {}
self.search_options = {}
self.immutable! if self.class.immutable_by_default?
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(*args, &block) ⇒ Object
259
260
261
262
263
264
265
266
267
268
|
# File 'lib/supernova/criteria.rb', line 259
def method_missing(*args, &block)
if Supernova::Collection.instance_methods.map(&:to_s).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)) else
super
end
end
|
Instance Attribute Details
#clazz ⇒ Object
Returns the value of attribute clazz.
5
6
7
|
# File 'lib/supernova/criteria.rb', line 5
def clazz
@clazz
end
|
#filters ⇒ Object
Returns the value of attribute filters.
5
6
7
|
# File 'lib/supernova/criteria.rb', line 5
def filters
@filters
end
|
#results ⇒ Object
Returns the value of attribute results.
5
6
7
|
# File 'lib/supernova/criteria.rb', line 5
def results
@results
end
|
#search_options ⇒ Object
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
.immutable_by_default! ⇒ Object
21
22
23
|
# File 'lib/supernova/criteria.rb', line 21
def immutable_by_default!
@immutable_by_default = true
end
|
.immutable_by_default? ⇒ Boolean
29
30
31
|
# File 'lib/supernova/criteria.rb', line 29
def immutable_by_default?
@immutable_by_default == true
end
|
.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
|
.mutable_by_default! ⇒ Object
25
26
27
|
# File 'lib/supernova/criteria.rb', line 25
def mutable_by_default!
@immutable_by_default = false
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
53
54
55
|
# File 'lib/supernova/criteria.rb', line 53
def attribute_mapping(mapping)
merge_search_options :attribute_mapping, mapping
end
|
#clone ⇒ Object
160
161
162
|
# File 'lib/supernova/criteria.rb', line 160
def clone
Marshal.load(Marshal.dump(self))
end
|
#conditions(filters) ⇒ Object
103
104
105
|
# File 'lib/supernova/criteria.rb', line 103
def conditions(filters)
merge_filters :conditions, filters
end
|
#current_page ⇒ Object
228
229
230
|
# File 'lib/supernova/criteria.rb', line 228
def current_page
(:page) || 1
end
|
#except(key) ⇒ Object
172
173
174
175
176
|
# File 'lib/supernova/criteria.rb', line 172
def except(key)
self_or_clone.tap do |soc|
soc.search_options.delete(key)
end
end
|
#execute ⇒ Object
224
225
226
|
# File 'lib/supernova/criteria.rb', line 224
def execute
implement_in_subclass
end
|
#facet_fields(*fields) ⇒ Object
95
96
97
|
# File 'lib/supernova/criteria.rb', line 95
def facet_fields(*fields)
merge_filters_array :facets, fields
end
|
#facet_queries(hash) ⇒ Object
99
100
101
|
# File 'lib/supernova/criteria.rb', line 99
def facet_queries(hash)
merge_search_options :facet_queries, hash
end
|
#for_classes(clazzes) ⇒ Object
49
50
51
|
# File 'lib/supernova/criteria.rb', line 49
def for_classes(clazzes)
merge_filters :classes, [clazzes].flatten
end
|
#group_by(group_option) ⇒ Object
65
66
67
|
# File 'lib/supernova/criteria.rb', line 65
def group_by(group_option)
merge_search_options :group_by, group_option
end
|
#immutable! ⇒ Object
41
42
43
|
# File 'lib/supernova/criteria.rb', line 41
def immutable!
@immutable = true
end
|
#immutable? ⇒ Boolean
45
46
47
|
# File 'lib/supernova/criteria.rb', line 45
def immutable?
@immutable == true
end
|
#implement_in_subclass ⇒ Object
244
245
246
|
# File 'lib/supernova/criteria.rb', line 244
def implement_in_subclass
raise "implement in subclass"
end
|
#limit(limit_option) ⇒ Object
61
62
63
|
# File 'lib/supernova/criteria.rb', line 61
def limit(limit_option)
merge_search_options :limit, limit_option
end
|
#merge(other_criteria) ⇒ Object
248
249
250
251
252
253
254
255
256
257
|
# File 'lib/supernova/criteria.rb', line 248
def merge(other_criteria)
ret = self_or_clone
other_criteria.filters.each do |key, value|
ret = ret.merge_filters(key, value)
end
other_criteria.search_options.each do |key, value|
ret = ret.merge_search_options(key, value)
end
ret
end
|
#merge_filters(key, value) ⇒ Object
147
148
149
|
# File 'lib/supernova/criteria.rb', line 147
def merge_filters(key, value)
merge_filters_or_search_options(:filters, key, value)
end
|
#merge_filters_array(key, fields) ⇒ Object
151
152
153
154
155
156
157
158
|
# File 'lib/supernova/criteria.rb', line 151
def merge_filters_array(key, fields)
self_or_clone.tap do |soc|
soc.search_options[key] ||= Array.new
fields.flatten.each do |field|
soc.search_options[key] << field if !soc.search_options[key].include?(field)
end
end
end
|
#merge_filters_or_search_options(reference_method, key, value) ⇒ Object
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
# File 'lib/supernova/criteria.rb', line 182
def merge_filters_or_search_options(reference_method, key, value)
self_or_clone.tap do |soc|
reference = soc.send(reference_method)
if key == :with
reference[:with] ||= Array.new
if valid_with_filter?(value)
if value.is_a?(Array)
reference[:with] += value
else
reference[:with] << value
end
end
elsif value.is_a?(Hash)
reference[key] ||= Hash.new
reference[key].merge!(value)
elsif [:select, :order].include?(key)
reference[key] ||= Array.new
reference[key] += (value || [])
else
reference[key] = value
end
end
end
|
#merge_search_options(key, value) ⇒ Object
168
169
170
|
# File 'lib/supernova/criteria.rb', line 168
def merge_search_options(key, value)
merge_filters_or_search_options(:search_options, key, value)
end
|
#named_scope_class(clazz) ⇒ Object
270
271
272
|
# File 'lib/supernova/criteria.rb', line 270
def named_scope_class(clazz)
merge_search_options :named_scope_class, clazz
end
|
#named_scope_defined?(name) ⇒ Boolean
274
275
276
|
# File 'lib/supernova/criteria.rb', line 274
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
119
120
121
|
# File 'lib/supernova/criteria.rb', line 119
def near(*coordinates)
merge_search_options :geo_center, normalize_coordinates(*coordinates)
end
|
#normalize_coordinates(*args) ⇒ Object
131
132
133
134
135
136
137
138
|
# File 'lib/supernova/criteria.rb', line 131
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
127
128
129
|
# File 'lib/supernova/criteria.rb', line 127
def options(options_hash)
merge_search_options :custom_options, options_hash
end
|
#order(*order_options) ⇒ Object
57
58
59
|
# File 'lib/supernova/criteria.rb', line 57
def order(*order_options)
merge_search_options :order, order_options
end
|
#paginate(pagination_options) ⇒ Object
107
108
109
|
# File 'lib/supernova/criteria.rb', line 107
def paginate()
merge_search_options :pagination,
end
|
238
239
240
241
242
|
# File 'lib/supernova/criteria.rb', line 238
def (attribute)
if self.search_options[:pagination] && self.search_options[:pagination][attribute].to_i > 0
self.search_options[:pagination][attribute]
end
end
|
#per_page ⇒ Object
232
233
234
235
236
|
# File 'lib/supernova/criteria.rb', line 232
def per_page
ret = self.search_options[:pagination][:per_page] if self.search_options[:pagination]
ret = DEFAULT_PER_PAGE if ret.nil?
ret
end
|
#populate ⇒ Object
210
211
212
213
|
# File 'lib/supernova/criteria.rb', line 210
def populate
@results = execute if !populated?
self
end
|
#populated? ⇒ Boolean
220
221
222
|
# File 'lib/supernova/criteria.rb', line 220
def populated?
instance_variables.map(&:to_s).include?("@results")
end
|
#read_first_attribute(object, *keys) ⇒ Object
140
141
142
143
144
145
|
# File 'lib/supernova/criteria.rb', line 140
def read_first_attribute(object, *keys)
keys.each do |key|
return object.send(key) if object.respond_to?(key)
end
nil
end
|
#rows(rows) ⇒ Object
111
112
113
|
# File 'lib/supernova/criteria.rb', line 111
def rows(rows)
merge_search_options :rows, rows
end
|
#search(*terms) ⇒ Object
69
70
71
|
# File 'lib/supernova/criteria.rb', line 69
def search(*terms)
merge_filters_array :search, terms
end
|
#select(*fields) ⇒ Object
91
92
93
|
# File 'lib/supernova/criteria.rb', line 91
def select(*fields)
merge_filters_array :select, fields
end
|
#self_or_clone ⇒ Object
164
165
166
|
# File 'lib/supernova/criteria.rb', line 164
def self_or_clone
immutable? ? clone : self
end
|
#start(start) ⇒ Object
115
116
117
|
# File 'lib/supernova/criteria.rb', line 115
def start(start)
merge_search_options :start, start
end
|
#to_a ⇒ Object
215
216
217
218
|
# File 'lib/supernova/criteria.rb', line 215
def to_a
populate
results
end
|
#to_parameters ⇒ Object
206
207
208
|
# File 'lib/supernova/criteria.rb', line 206
def to_parameters
implement_in_subclass
end
|
#valid_with_filter?(value) ⇒ Boolean
178
179
180
|
# File 'lib/supernova/criteria.rb', line 178
def valid_with_filter?(value)
!(value.respond_to?(:blank?) && value.blank?) && !(value.respond_to?(:empty?) && value.empty?)
end
|
#where(*args) ⇒ Object
77
78
79
|
# File 'lib/supernova/criteria.rb', line 77
def where(*args)
with(*args)
end
|
#with(filters) ⇒ Object
73
74
75
|
# File 'lib/supernova/criteria.rb', line 73
def with(filters)
merge_search_options :with, filters
end
|
#within(distance) ⇒ Object
123
124
125
|
# File 'lib/supernova/criteria.rb', line 123
def within(distance)
merge_search_options :geo_distance, distance
end
|
#without(filters) ⇒ Object
81
82
83
84
85
86
87
88
89
|
# File 'lib/supernova/criteria.rb', line 81
def without(filters)
self_or_clone.tap do |soc|
soc.filters[:without] ||= Hash.new
filters.each do |key, value|
soc.filters[:without][key] ||= Array.new
soc.filters[:without][key] << value if !soc.filters[:without][key].include?(value)
end
end
end
|