mongoid 1.0.6 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY +39 -0
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/mongoid.rb +3 -1
- data/lib/mongoid/associations.rb +5 -5
- data/lib/mongoid/associations/has_many.rb +8 -2
- data/lib/mongoid/associations/has_many_related.rb +10 -4
- data/lib/mongoid/attributes.rb +19 -13
- data/lib/mongoid/commands.rb +12 -6
- data/lib/mongoid/commands/create.rb +2 -2
- data/lib/mongoid/commands/delete_all.rb +1 -1
- data/lib/mongoid/commands/save.rb +2 -2
- data/lib/mongoid/components.rb +1 -0
- data/lib/mongoid/contexts.rb +4 -0
- data/lib/mongoid/contexts/enumerable.rb +105 -0
- data/lib/mongoid/contexts/mongo.rb +228 -0
- data/lib/mongoid/contexts/paging.rb +42 -0
- data/lib/mongoid/criteria.rb +42 -191
- data/lib/mongoid/document.rb +19 -13
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/extensions/array/accessors.rb +3 -1
- data/lib/mongoid/extensions/float/conversions.rb +1 -1
- data/lib/mongoid/extensions/hash/accessors.rb +1 -1
- data/lib/mongoid/extensions/integer/conversions.rb +1 -0
- data/lib/mongoid/fields.rb +6 -5
- data/lib/mongoid/matchers.rb +36 -0
- data/lib/mongoid/matchers/all.rb +11 -0
- data/lib/mongoid/matchers/default.rb +20 -0
- data/lib/mongoid/matchers/exists.rb +13 -0
- data/lib/mongoid/matchers/gt.rb +11 -0
- data/lib/mongoid/matchers/gte.rb +11 -0
- data/lib/mongoid/matchers/in.rb +11 -0
- data/lib/mongoid/matchers/lt.rb +11 -0
- data/lib/mongoid/matchers/lte.rb +11 -0
- data/lib/mongoid/matchers/ne.rb +11 -0
- data/lib/mongoid/matchers/nin.rb +11 -0
- data/lib/mongoid/matchers/size.rb +11 -0
- data/lib/mongoid/scope.rb +17 -1
- data/mongoid.gemspec +51 -5
- data/spec/integration/mongoid/associations_spec.rb +67 -5
- data/spec/integration/mongoid/attributes_spec.rb +22 -0
- data/spec/integration/mongoid/commands_spec.rb +51 -12
- data/spec/integration/mongoid/criteria_spec.rb +3 -3
- data/spec/integration/mongoid/document_spec.rb +8 -8
- data/spec/integration/mongoid/finders_spec.rb +1 -1
- data/spec/integration/mongoid/inheritance_spec.rb +6 -0
- data/spec/integration/mongoid/named_scope_spec.rb +1 -1
- data/spec/spec_helper.rb +47 -6
- data/spec/unit/mongoid/associations/has_many_related_spec.rb +42 -0
- data/spec/unit/mongoid/associations/has_many_spec.rb +40 -1
- data/spec/unit/mongoid/attributes_spec.rb +1 -1
- data/spec/unit/mongoid/commands/create_spec.rb +3 -3
- data/spec/unit/mongoid/commands/delete_all_spec.rb +2 -2
- data/spec/unit/mongoid/commands/save_spec.rb +2 -2
- data/spec/unit/mongoid/commands_spec.rb +12 -12
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +208 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +370 -0
- data/spec/unit/mongoid/criteria_spec.rb +182 -21
- data/spec/unit/mongoid/extensions/array/accessors_spec.rb +9 -9
- data/spec/unit/mongoid/extensions/date/conversions_spec.rb +2 -1
- data/spec/unit/mongoid/extensions/float/conversions_spec.rb +4 -4
- data/spec/unit/mongoid/extensions/integer/conversions_spec.rb +1 -1
- data/spec/unit/mongoid/fields_spec.rb +3 -3
- data/spec/unit/mongoid/identity_spec.rb +2 -2
- data/spec/unit/mongoid/matchers/all_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/default_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/exists_spec.rb +56 -0
- data/spec/unit/mongoid/matchers/gt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/gte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/in_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/lt_spec.rb +39 -0
- data/spec/unit/mongoid/matchers/lte_spec.rb +49 -0
- data/spec/unit/mongoid/matchers/ne_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/nin_spec.rb +27 -0
- data/spec/unit/mongoid/matchers/size_spec.rb +27 -0
- data/spec/unit/mongoid/matchers_spec.rb +329 -0
- data/spec/unit/mongoid/scope_spec.rb +70 -0
- data/spec/unit/mongoid/timestamps_spec.rb +2 -2
- metadata +50 -4
data/HISTORY
CHANGED
@@ -1,3 +1,42 @@
|
|
1
|
+
=== 1.0.7
|
2
|
+
- Nil attributes no longer persist nil values to the
|
3
|
+
database - the field will just not exist.
|
4
|
+
|
5
|
+
- create! and save! will now properly raise an error
|
6
|
+
when a database operation fails. This is handled
|
7
|
+
by using :safe => true as an option to
|
8
|
+
collection.save.
|
9
|
+
|
10
|
+
- Setting blank numbers casts to nil.
|
11
|
+
|
12
|
+
- Criteria and named scopes can now be used on has
|
13
|
+
many relationships. They can be chained with each
|
14
|
+
other off the association chain.
|
15
|
+
|
16
|
+
- Mongoid can now determine if a document matches a
|
17
|
+
mongodb selector without hitting the database via
|
18
|
+
Document#matches?(selector).
|
19
|
+
|
20
|
+
- Overall performance improvements in all areas.
|
21
|
+
|
22
|
+
- Ruby 1.9 compatibility fixes.
|
23
|
+
|
24
|
+
- Has many related now supports finding by id or
|
25
|
+
by an optional :all, :first, :last with a
|
26
|
+
conditions hash.
|
27
|
+
|
28
|
+
=== 1.0.6
|
29
|
+
|
30
|
+
- Preventing the setting of empty values in attributes.
|
31
|
+
|
32
|
+
- Better inspect formatting
|
33
|
+
|
34
|
+
=== 1.0.5
|
35
|
+
|
36
|
+
- Has one and has many associations now set the parent
|
37
|
+
object first before writing the attributes on
|
38
|
+
#build and #create.
|
39
|
+
|
1
40
|
=== 1.0.4
|
2
41
|
- Modified criteria to use the querying class
|
3
42
|
when instantiating documents if there are no
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ begin
|
|
12
12
|
gem.homepage = "http://mongoid.org"
|
13
13
|
gem.authors = ["Durran Jordan"]
|
14
14
|
|
15
|
-
gem.add_dependency("activesupport", "
|
15
|
+
gem.add_dependency("activesupport", "<= 2.3.5")
|
16
16
|
gem.add_dependency("mongo", ">= 0.18.2")
|
17
17
|
gem.add_dependency("durran-validatable", ">= 2.0.1")
|
18
18
|
gem.add_dependency("leshill-will_paginate", ">= 2.3.11")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0
|
1
|
+
1.1.0
|
data/lib/mongoid.rb
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
require "rubygems"
|
23
23
|
|
24
|
-
gem "activesupport", ">= 2.2.2"
|
24
|
+
gem "activesupport", ">= 2.2.2", "<3.0.pre"
|
25
25
|
gem "mongo", ">= 0.18.2"
|
26
26
|
gem "durran-validatable", ">= 2.0.1"
|
27
27
|
gem "leshill-will_paginate", ">= 2.3.11"
|
@@ -43,6 +43,7 @@ require "mongoid/attributes"
|
|
43
43
|
require "mongoid/callbacks"
|
44
44
|
require "mongoid/commands"
|
45
45
|
require "mongoid/config"
|
46
|
+
require "mongoid/contexts"
|
46
47
|
require "mongoid/complex_criterion"
|
47
48
|
require "mongoid/criteria"
|
48
49
|
require "mongoid/extensions"
|
@@ -52,6 +53,7 @@ require "mongoid/fields"
|
|
52
53
|
require "mongoid/finders"
|
53
54
|
require "mongoid/identity"
|
54
55
|
require "mongoid/indexes"
|
56
|
+
require "mongoid/matchers"
|
55
57
|
require "mongoid/memoization"
|
56
58
|
require "mongoid/named_scope"
|
57
59
|
require "mongoid/scope"
|
data/lib/mongoid/associations.rb
CHANGED
@@ -13,7 +13,7 @@ module Mongoid # :nodoc:
|
|
13
13
|
base.class_eval do
|
14
14
|
# Associations need to inherit down the chain.
|
15
15
|
class_inheritable_accessor :associations
|
16
|
-
self.associations = {}
|
16
|
+
self.associations = {}
|
17
17
|
|
18
18
|
include InstanceMethods
|
19
19
|
extend ClassMethods
|
@@ -203,7 +203,7 @@ module Mongoid # :nodoc:
|
|
203
203
|
#
|
204
204
|
# <tt>Person.reflect_on_association(:addresses)</tt>
|
205
205
|
def reflect_on_association(name)
|
206
|
-
association = associations[name]
|
206
|
+
association = associations[name.to_s]
|
207
207
|
association ? association.macro : nil
|
208
208
|
end
|
209
209
|
|
@@ -212,7 +212,7 @@ module Mongoid # :nodoc:
|
|
212
212
|
# then adds the accessors for the association. The defined setters and
|
213
213
|
# getters for the associations will perform the necessary memoization.
|
214
214
|
def add_association(type, options)
|
215
|
-
name = options.name
|
215
|
+
name = options.name.to_s
|
216
216
|
associations[name] = type
|
217
217
|
define_method(name) do
|
218
218
|
memoized(name) { type.instantiate(self, options) }
|
@@ -225,7 +225,7 @@ module Mongoid # :nodoc:
|
|
225
225
|
# Adds a builder for a has_one association. This comes in the form of
|
226
226
|
# build_name(attributes)
|
227
227
|
def add_builder(type, options)
|
228
|
-
name = options.name
|
228
|
+
name = options.name.to_s
|
229
229
|
define_method("build_#{name}") do |attrs|
|
230
230
|
reset(name) { type.new(self, attrs, options) }
|
231
231
|
end
|
@@ -234,7 +234,7 @@ module Mongoid # :nodoc:
|
|
234
234
|
# Adds a creator for a has_one association. This comes in the form of
|
235
235
|
# create_name(attributes)
|
236
236
|
def add_creator(type, options)
|
237
|
-
name = options.name
|
237
|
+
name = options.name.to_s
|
238
238
|
define_method("create_#{name}") do |attrs|
|
239
239
|
document = send("build_#{name}", attrs)
|
240
240
|
document.save; document
|
@@ -41,7 +41,6 @@ module Mongoid #:nodoc:
|
|
41
41
|
object = type ? type.instantiate : @klass.instantiate
|
42
42
|
object.parentize(@parent, @association_name)
|
43
43
|
object.write_attributes(attrs)
|
44
|
-
object.identify
|
45
44
|
@documents << object
|
46
45
|
object
|
47
46
|
end
|
@@ -84,8 +83,15 @@ module Mongoid #:nodoc:
|
|
84
83
|
end : []
|
85
84
|
end
|
86
85
|
|
87
|
-
# Delegate all missing methods over to the documents array
|
86
|
+
# Delegate all missing methods over to the documents array unless a
|
87
|
+
# criteria or named scope exists on the association class. If that is the
|
88
|
+
# case then call that method.
|
88
89
|
def method_missing(name, *args, &block)
|
90
|
+
unless @documents.respond_to?(name)
|
91
|
+
criteria = @klass.send(name, *args)
|
92
|
+
criteria.documents = @documents
|
93
|
+
return criteria
|
94
|
+
end
|
89
95
|
@documents.send(name, *args, &block)
|
90
96
|
end
|
91
97
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
3
|
module Associations #:nodoc:
|
4
|
-
class HasManyRelated
|
4
|
+
class HasManyRelated #:nodoc:
|
5
|
+
include Proxy
|
5
6
|
|
6
7
|
attr_reader :klass
|
7
8
|
|
@@ -46,8 +47,9 @@ module Mongoid #:nodoc:
|
|
46
47
|
|
47
48
|
# Finds a document in this association.
|
48
49
|
# If an id is passed, will return the document for that id.
|
49
|
-
def find(
|
50
|
-
@
|
50
|
+
def find(*args)
|
51
|
+
args[1][:conditions].merge!(@foreign_key.to_sym => @parent.id) if args.size > 1
|
52
|
+
@klass.find(*args)
|
51
53
|
end
|
52
54
|
|
53
55
|
# Initializing a related association only requires looking up the objects
|
@@ -61,7 +63,11 @@ module Mongoid #:nodoc:
|
|
61
63
|
@parent, @klass = document, options.klass
|
62
64
|
@foreign_key = document.class.to_s.foreign_key
|
63
65
|
@documents = @klass.all(:conditions => { @foreign_key => document.id })
|
64
|
-
|
66
|
+
end
|
67
|
+
|
68
|
+
# Delegate all missing methods over to the documents array.
|
69
|
+
def method_missing(name, *args, &block)
|
70
|
+
@documents.send(name, *args, &block)
|
65
71
|
end
|
66
72
|
|
67
73
|
# Delegates to <<
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -11,12 +11,12 @@ module Mongoid #:nodoc:
|
|
11
11
|
# Get the id associated with this object. This will pull the _id value out
|
12
12
|
# of the attributes +Hash+.
|
13
13
|
def id
|
14
|
-
@attributes[
|
14
|
+
@attributes["_id"]
|
15
15
|
end
|
16
16
|
|
17
17
|
# Set the id of the +Document+ to a new one.
|
18
18
|
def id=(new_id)
|
19
|
-
@attributes[
|
19
|
+
@attributes["_id"] = new_id
|
20
20
|
end
|
21
21
|
|
22
22
|
alias :_id :id
|
@@ -26,7 +26,12 @@ module Mongoid #:nodoc:
|
|
26
26
|
def method_missing(name, *args)
|
27
27
|
attr = name.to_s
|
28
28
|
return super unless @attributes.has_key?(attr.reader)
|
29
|
-
attr.writer?
|
29
|
+
if attr.writer?
|
30
|
+
# "args.size > 1" allows to simulate 1.8 behavior of "*args"
|
31
|
+
@attributes[attr.reader] = (args.size > 1) ? args : args.first
|
32
|
+
else
|
33
|
+
@attributes[attr.reader]
|
34
|
+
end
|
30
35
|
end
|
31
36
|
|
32
37
|
# Process the provided attributes casting them to their proper values if a
|
@@ -36,9 +41,9 @@ module Mongoid #:nodoc:
|
|
36
41
|
def process(attrs = {})
|
37
42
|
attrs.each_pair do |key, value|
|
38
43
|
if Mongoid.allow_dynamic_fields && !respond_to?("#{key}=")
|
39
|
-
@attributes[key] = value
|
44
|
+
@attributes[key.to_s] = value
|
40
45
|
else
|
41
|
-
send("#{key}=", value)
|
46
|
+
send("#{key}=", value) if value
|
42
47
|
end
|
43
48
|
end
|
44
49
|
end
|
@@ -54,7 +59,8 @@ module Mongoid #:nodoc:
|
|
54
59
|
#
|
55
60
|
# <tt>person.read_attribute(:title)</tt>
|
56
61
|
def read_attribute(name)
|
57
|
-
|
62
|
+
access = name.to_s
|
63
|
+
fields[access].get(@attributes[access])
|
58
64
|
end
|
59
65
|
|
60
66
|
# Remove a value from the +Document+ attributes. If the value does not exist
|
@@ -68,19 +74,19 @@ module Mongoid #:nodoc:
|
|
68
74
|
#
|
69
75
|
# <tt>person.remove_attribute(:title)</tt>
|
70
76
|
def remove_attribute(name)
|
71
|
-
@attributes.delete(name)
|
77
|
+
@attributes.delete(name.to_s)
|
72
78
|
end
|
73
79
|
|
74
80
|
# Returns the object type. This corresponds to the name of the class that
|
75
81
|
# this +Document+ is, which is used in determining the class to
|
76
82
|
# instantiate in various cases.
|
77
83
|
def _type
|
78
|
-
@attributes[
|
84
|
+
@attributes["_type"]
|
79
85
|
end
|
80
86
|
|
81
87
|
# Set the type of the +Document+. This should be the name of the class.
|
82
88
|
def _type=(new_type)
|
83
|
-
@attributes[
|
89
|
+
@attributes["_type"] = new_type
|
84
90
|
end
|
85
91
|
|
86
92
|
# Write a single attribute to the +Document+ attribute +Hash+. This will
|
@@ -99,10 +105,9 @@ module Mongoid #:nodoc:
|
|
99
105
|
# This will also cause the observing +Document+ to notify it's parent if
|
100
106
|
# there is any.
|
101
107
|
def write_attribute(name, value)
|
102
|
-
|
103
|
-
@attributes[
|
104
|
-
|
105
|
-
notify
|
108
|
+
access = name.to_s
|
109
|
+
@attributes[access] = fields[access].set(value)
|
110
|
+
notify unless id.blank?
|
106
111
|
end
|
107
112
|
|
108
113
|
# Writes the supplied attributes +Hash+ to the +Document+. This will only
|
@@ -121,6 +126,7 @@ module Mongoid #:nodoc:
|
|
121
126
|
# there is any.
|
122
127
|
def write_attributes(attrs = nil)
|
123
128
|
process(attrs || {})
|
129
|
+
identify if id.blank?
|
124
130
|
notify
|
125
131
|
end
|
126
132
|
|
data/lib/mongoid/commands.rb
CHANGED
@@ -59,10 +59,10 @@ module Mongoid #:nodoc:
|
|
59
59
|
# <tt>document.save(false) # save without validations</tt>
|
60
60
|
#
|
61
61
|
# Returns: true if validation passes, false if not.
|
62
|
-
def save(validate = true)
|
62
|
+
def save(validate = true, safe = false)
|
63
63
|
new = new_record?
|
64
64
|
run_callbacks(:before_create) if new
|
65
|
-
saved = Save.execute(self, validate)
|
65
|
+
saved = Save.execute(self, validate, safe)
|
66
66
|
run_callbacks(:after_create) if new
|
67
67
|
saved
|
68
68
|
end
|
@@ -76,7 +76,7 @@ module Mongoid #:nodoc:
|
|
76
76
|
#
|
77
77
|
# Returns: true if validation passes
|
78
78
|
def save!
|
79
|
-
return save(true) || (raise Errors::Validations.new(self.errors))
|
79
|
+
return save(true, true) || (raise Errors::Validations.new(self.errors))
|
80
80
|
end
|
81
81
|
|
82
82
|
# Update the document attributes and persist the document to the
|
@@ -86,7 +86,7 @@ module Mongoid #:nodoc:
|
|
86
86
|
#
|
87
87
|
# <tt>document.update_attributes(:title => "Test")</tt>
|
88
88
|
def update_attributes(attrs = {})
|
89
|
-
|
89
|
+
set_attributes(attrs); save
|
90
90
|
end
|
91
91
|
|
92
92
|
# Update the document attributes and persist the document to the
|
@@ -96,7 +96,13 @@ module Mongoid #:nodoc:
|
|
96
96
|
#
|
97
97
|
# <tt>document.update_attributes!(:title => "Test")</tt>
|
98
98
|
def update_attributes!(attrs = {})
|
99
|
-
|
99
|
+
set_attributes(attrs); save!
|
100
|
+
end
|
101
|
+
|
102
|
+
protected
|
103
|
+
def set_attributes(attrs = {})
|
104
|
+
run_callbacks(:before_update)
|
105
|
+
write_attributes(attrs)
|
100
106
|
end
|
101
107
|
|
102
108
|
end
|
@@ -126,7 +132,7 @@ module Mongoid #:nodoc:
|
|
126
132
|
#
|
127
133
|
# Returns: the +Document+.
|
128
134
|
def create!(attributes = {})
|
129
|
-
document = Create.execute(new(attributes))
|
135
|
+
document = Create.execute(new(attributes), true, true)
|
130
136
|
raise Errors::Validations.new(self.errors) unless document.errors.empty?
|
131
137
|
return document
|
132
138
|
end
|
@@ -10,9 +10,9 @@ module Mongoid #:nodoc:
|
|
10
10
|
# doc: A new +Document+ that is going to be persisted.
|
11
11
|
#
|
12
12
|
# Returns: +Document+.
|
13
|
-
def self.execute(doc, validate = true)
|
13
|
+
def self.execute(doc, validate = true, safe = false)
|
14
14
|
doc.run_callbacks :before_create
|
15
|
-
Save.execute(doc, validate)
|
15
|
+
Save.execute(doc, validate, safe)
|
16
16
|
doc.run_callbacks :after_create
|
17
17
|
return doc
|
18
18
|
end
|
@@ -15,7 +15,7 @@ module Mongoid #:nodoc:
|
|
15
15
|
# <tt>DeleteAll.execute(Person, :conditions => { :field => "value" })</tt>
|
16
16
|
def self.execute(klass, params = {})
|
17
17
|
collection = klass.collection
|
18
|
-
|
18
|
+
collection.remove((params[:conditions] || {}).merge(:_type => klass.name))
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -10,12 +10,12 @@ module Mongoid #:nodoc:
|
|
10
10
|
# doc: A +Document+ that is going to be persisted.
|
11
11
|
#
|
12
12
|
# Returns: +Document+ if validation passes, +false+ if not.
|
13
|
-
def self.execute(doc, validate = true)
|
13
|
+
def self.execute(doc, validate = true, safe = false)
|
14
14
|
return false if validate && !doc.valid?
|
15
15
|
doc.run_callbacks :before_save
|
16
16
|
parent = doc._parent
|
17
17
|
doc.new_record = false
|
18
|
-
if parent ? Save.execute(parent, validate) : doc.collection.save(doc.attributes)
|
18
|
+
if parent ? Save.execute(parent, validate, safe) : doc.collection.save(doc.attributes, :safe => safe)
|
19
19
|
doc.run_callbacks :after_save
|
20
20
|
return true
|
21
21
|
else
|
data/lib/mongoid/components.rb
CHANGED
@@ -0,0 +1,105 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
module Contexts #:nodoc:
|
4
|
+
class Enumerable
|
5
|
+
include Paging
|
6
|
+
attr_reader :selector, :options, :documents
|
7
|
+
|
8
|
+
delegate :first, :last, :to => :documents
|
9
|
+
|
10
|
+
# Return aggregation counts of the grouped documents. This will count by
|
11
|
+
# the first field provided in the fields array.
|
12
|
+
#
|
13
|
+
# Returns:
|
14
|
+
#
|
15
|
+
# A +Hash+ with field values as keys, count as values
|
16
|
+
def aggregate
|
17
|
+
counts = {}
|
18
|
+
group.each_pair { |key, value| counts[key] = value.size }
|
19
|
+
counts
|
20
|
+
end
|
21
|
+
|
22
|
+
# Gets the number of documents in the array. Delegates to size.
|
23
|
+
def count
|
24
|
+
@documents.size
|
25
|
+
end
|
26
|
+
|
27
|
+
# Groups the documents by the first field supplied in the field options.
|
28
|
+
#
|
29
|
+
# Returns:
|
30
|
+
#
|
31
|
+
# A +Hash+ with field values as keys, arrays of documents as values.
|
32
|
+
def group
|
33
|
+
field = @options[:fields].first
|
34
|
+
@documents.group_by { |doc| doc.send(field) }
|
35
|
+
end
|
36
|
+
|
37
|
+
# Enumerable implementation of execute. Returns matching documents for
|
38
|
+
# the selector, and adds options if supplied.
|
39
|
+
#
|
40
|
+
# Returns:
|
41
|
+
#
|
42
|
+
# An +Array+ of documents that matched the selector.
|
43
|
+
def execute
|
44
|
+
@documents.select { |document| document.matches?(@selector) }
|
45
|
+
end
|
46
|
+
|
47
|
+
# Create the new enumerable context. This will need the selector and
|
48
|
+
# options from a +Criteria+ and a documents array that is the underlying
|
49
|
+
# array of embedded documents from a has many association.
|
50
|
+
#
|
51
|
+
# Example:
|
52
|
+
#
|
53
|
+
# <tt>Mongoid::Contexts::Enumerable.new(selector, options, docs)</tt>
|
54
|
+
def initialize(selector, options, documents)
|
55
|
+
@selector, @options, @documents = selector, options, documents
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get the largest value for the field in all the documents.
|
59
|
+
#
|
60
|
+
# Returns:
|
61
|
+
#
|
62
|
+
# The numerical largest value.
|
63
|
+
def max(field)
|
64
|
+
largest = @documents.inject(nil) do |memo, doc|
|
65
|
+
value = doc.send(field)
|
66
|
+
(memo && memo >= value) ? memo : value
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Get the smallest value for the field in all the documents.
|
71
|
+
#
|
72
|
+
# Returns:
|
73
|
+
#
|
74
|
+
# The numerical smallest value.
|
75
|
+
def min(field)
|
76
|
+
smallest = @documents.inject(nil) do |memo, doc|
|
77
|
+
value = doc.send(field)
|
78
|
+
(memo && memo <= value) ? memo : value
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# Get one document.
|
83
|
+
#
|
84
|
+
# Returns:
|
85
|
+
#
|
86
|
+
# The first document in the +Array+
|
87
|
+
def one
|
88
|
+
@documents.first
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get the sum of the field values for all the documents.
|
92
|
+
#
|
93
|
+
# Returns:
|
94
|
+
#
|
95
|
+
# The numerical sum of all the document field values.
|
96
|
+
def sum(field)
|
97
|
+
sum = @documents.inject(nil) do |memo, doc|
|
98
|
+
value = doc.send(field)
|
99
|
+
memo ? memo += value : value
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|