mongoid 1.0.6 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|