mongoid 1.2.8 → 1.2.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/mongoid.rb +2 -3
- data/lib/mongoid/associations.rb +5 -3
- data/lib/mongoid/associations/belongs_to_related.rb +6 -9
- data/lib/mongoid/associations/has_many.rb +2 -0
- data/lib/mongoid/associations/has_many_related.rb +10 -0
- data/lib/mongoid/attributes.rb +6 -1
- data/lib/mongoid/commands.rb +2 -10
- data/lib/mongoid/components.rb +11 -12
- data/lib/mongoid/contexts/enumerable.rb +21 -11
- data/lib/mongoid/contexts/mongo.rb +40 -1
- data/lib/mongoid/criteria.rb +3 -29
- data/lib/mongoid/criterion/inclusion.rb +2 -1
- data/lib/mongoid/document.rb +5 -6
- data/lib/mongoid/extensions.rb +10 -0
- data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
- data/lib/mongoid/extensions/binary/conversions.rb +17 -0
- data/lib/mongoid/{caching.rb → extras.rb} +26 -3
- data/lib/mongoid/field.rb +20 -7
- data/lib/mongoid/finders.rb +10 -80
- data/mongoid.gemspec +15 -13
- data/spec/integration/mongoid/document_spec.rb +1 -1
- data/spec/models/person.rb +1 -0
- data/spec/unit/mongoid/associations/belongs_to_related_spec.rb +4 -0
- data/spec/unit/mongoid/associations/has_many_related_spec.rb +42 -13
- data/spec/unit/mongoid/associations/has_many_spec.rb +12 -7
- data/spec/unit/mongoid/associations_spec.rb +16 -0
- data/spec/unit/mongoid/attributes_spec.rb +23 -0
- data/spec/unit/mongoid/commands/destroy_spec.rb +3 -0
- data/spec/unit/mongoid/commands_spec.rb +4 -11
- data/spec/unit/mongoid/contexts/enumerable_spec.rb +16 -0
- data/spec/unit/mongoid/contexts/mongo_spec.rb +96 -0
- data/spec/unit/mongoid/criteria_spec.rb +11 -4
- data/spec/unit/mongoid/document_spec.rb +11 -0
- data/spec/unit/mongoid/extensions/big_decimal/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/extensions/binary/conversions_spec.rb +22 -0
- data/spec/unit/mongoid/{enslavement_spec.rb → extras_spec.rb} +55 -2
- data/spec/unit/mongoid/field_spec.rb +62 -0
- data/spec/unit/mongoid/finders_spec.rb +36 -0
- metadata +69 -37
- data/HISTORY +0 -342
- data/lib/mongoid/enslavement.rb +0 -38
- data/spec/unit/mongoid/caching_spec.rb +0 -63
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ begin
|
|
15
15
|
gem.add_dependency("activesupport", "<= 2.3.5")
|
16
16
|
gem.add_dependency("mongo", ">= 0.18.3")
|
17
17
|
gem.add_dependency("durran-validatable", ">= 2.0.1")
|
18
|
-
gem.add_dependency("will_paginate", "<
|
18
|
+
gem.add_dependency("will_paginate", "< 2.9")
|
19
19
|
|
20
20
|
gem.add_development_dependency("rspec", ">= 1.2.9")
|
21
21
|
gem.add_development_dependency("mocha", ">= 0.9.8")
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.9
|
data/lib/mongoid.rb
CHANGED
@@ -24,7 +24,7 @@ require "rubygems"
|
|
24
24
|
gem "activesupport", ">= 2.2.2", "<3.0.pre"
|
25
25
|
gem "mongo", ">= 0.18.3"
|
26
26
|
gem "durran-validatable", ">= 2.0.1"
|
27
|
-
gem "will_paginate", ">= 2.3.11", "<
|
27
|
+
gem "will_paginate", ">= 2.3.11", "< 2.9"
|
28
28
|
|
29
29
|
require "delegate"
|
30
30
|
require "observer"
|
@@ -39,7 +39,6 @@ require "will_paginate/collection"
|
|
39
39
|
require "mongo"
|
40
40
|
require "mongoid/associations"
|
41
41
|
require "mongoid/attributes"
|
42
|
-
require "mongoid/caching"
|
43
42
|
require "mongoid/callbacks"
|
44
43
|
require "mongoid/collection"
|
45
44
|
require "mongoid/commands"
|
@@ -47,8 +46,8 @@ require "mongoid/config"
|
|
47
46
|
require "mongoid/contexts"
|
48
47
|
require "mongoid/criteria"
|
49
48
|
require "mongoid/cursor"
|
50
|
-
require "mongoid/enslavement"
|
51
49
|
require "mongoid/extensions"
|
50
|
+
require "mongoid/extras"
|
52
51
|
require "mongoid/errors"
|
53
52
|
require "mongoid/factory"
|
54
53
|
require "mongoid/field"
|
data/lib/mongoid/associations.rb
CHANGED
@@ -93,8 +93,8 @@ module Mongoid # :nodoc:
|
|
93
93
|
options.merge(:name => name, :extend => block, :foreign_key => foreign_key(name, options))
|
94
94
|
)
|
95
95
|
add_association(Associations::BelongsToRelated, opts)
|
96
|
-
field
|
97
|
-
index
|
96
|
+
field(opts.foreign_key, :type => Mongoid.use_object_ids ? Mongo::ObjectID : String)
|
97
|
+
index(opts.foreign_key) unless self.embedded
|
98
98
|
end
|
99
99
|
|
100
100
|
# Adds the association from a parent document to its children. The name
|
@@ -249,7 +249,9 @@ module Mongoid # :nodoc:
|
|
249
249
|
name = options.name.to_s
|
250
250
|
define_method("create_#{name}") do |attrs|
|
251
251
|
document = send("build_#{name}", attrs)
|
252
|
-
document.
|
252
|
+
document.run_callbacks(:before_create)
|
253
|
+
document.save
|
254
|
+
document.run_callbacks(:after_create); document
|
253
255
|
end
|
254
256
|
end
|
255
257
|
|
@@ -41,19 +41,16 @@ module Mongoid #:nodoc:
|
|
41
41
|
#
|
42
42
|
# Options:
|
43
43
|
#
|
44
|
-
#
|
45
|
-
#
|
44
|
+
# target: The target(parent) object
|
45
|
+
# document: The +Document+ to update.
|
46
46
|
# options: The association +Options+
|
47
47
|
#
|
48
48
|
# Example:
|
49
49
|
#
|
50
|
-
# <tt>BelongsToRelated.update(
|
51
|
-
def update(target,
|
52
|
-
|
53
|
-
|
54
|
-
return instantiate(parent, options, target)
|
55
|
-
end
|
56
|
-
target
|
50
|
+
# <tt>BelongsToRelated.update(person, game, options)</tt>
|
51
|
+
def update(target, document, options)
|
52
|
+
document.send("#{options.foreign_key}=", target ? target.id : nil)
|
53
|
+
instantiate(document, options, target)
|
57
54
|
end
|
58
55
|
end
|
59
56
|
|
@@ -7,6 +7,7 @@ module Mongoid #:nodoc:
|
|
7
7
|
# Appends the object to the +Array+, setting its parent in
|
8
8
|
# the process.
|
9
9
|
def <<(*objects)
|
10
|
+
load_target
|
10
11
|
objects.flatten.each do |object|
|
11
12
|
object.send("#{@foreign_key}=", @parent.id)
|
12
13
|
@target << object
|
@@ -20,6 +21,7 @@ module Mongoid #:nodoc:
|
|
20
21
|
#
|
21
22
|
# Returns the newly created object.
|
22
23
|
def build(attributes = {})
|
24
|
+
load_target
|
23
25
|
name = @parent.class.to_s.underscore
|
24
26
|
object = @klass.instantiate(attributes.merge(name => @parent))
|
25
27
|
@target << object
|
@@ -39,7 +41,9 @@ module Mongoid #:nodoc:
|
|
39
41
|
# Returns the newly created object.
|
40
42
|
def create(attributes)
|
41
43
|
object = build(attributes)
|
44
|
+
object.run_callbacks(:before_create)
|
42
45
|
object.save
|
46
|
+
object.run_callbacks(:after_create)
|
43
47
|
object
|
44
48
|
end
|
45
49
|
|
@@ -69,6 +73,12 @@ module Mongoid #:nodoc:
|
|
69
73
|
self << objects
|
70
74
|
end
|
71
75
|
|
76
|
+
protected
|
77
|
+
# Load the target entries if the document is new.
|
78
|
+
def load_target
|
79
|
+
@target = @target.entries if @parent.new_record?
|
80
|
+
end
|
81
|
+
|
72
82
|
class << self
|
73
83
|
# Preferred method for creating the new +HasManyRelated+ association.
|
74
84
|
#
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -42,7 +42,7 @@ module Mongoid #:nodoc:
|
|
42
42
|
(attrs || {}).each_pair do |key, value|
|
43
43
|
if set_allowed?(key)
|
44
44
|
@attributes[key.to_s] = value
|
45
|
-
|
45
|
+
elsif write_allowed?(key)
|
46
46
|
send("#{key}=", value)
|
47
47
|
end
|
48
48
|
end
|
@@ -148,6 +148,11 @@ module Mongoid #:nodoc:
|
|
148
148
|
end
|
149
149
|
end
|
150
150
|
|
151
|
+
# Return true if writing to the given field is allowed
|
152
|
+
def write_allowed?(key)
|
153
|
+
return true unless fields[key.to_s]
|
154
|
+
fields[key.to_s].accessible?
|
155
|
+
end
|
151
156
|
end
|
152
157
|
|
153
158
|
module ClassMethods
|
data/lib/mongoid/commands.rb
CHANGED
@@ -62,11 +62,7 @@ module Mongoid #:nodoc:
|
|
62
62
|
def save(validate = true)
|
63
63
|
new = new_record?
|
64
64
|
run_callbacks(:before_create) if new
|
65
|
-
|
66
|
-
saved = Save.execute(self, validate)
|
67
|
-
rescue Mongo::OperationFailure => e
|
68
|
-
errors.add(:mongoid, e.message)
|
69
|
-
end
|
65
|
+
saved = Save.execute(self, validate)
|
70
66
|
run_callbacks(:after_create) if new && saved
|
71
67
|
saved
|
72
68
|
end
|
@@ -125,11 +121,7 @@ module Mongoid #:nodoc:
|
|
125
121
|
# Returns: the +Document+.
|
126
122
|
def create(attributes = {})
|
127
123
|
document = new(attributes)
|
128
|
-
|
129
|
-
Create.execute(document)
|
130
|
-
rescue Mongo::OperationFailure => e
|
131
|
-
document.errors.add(:mongoid, e.message)
|
132
|
-
end
|
124
|
+
Create.execute(document)
|
133
125
|
document
|
134
126
|
end
|
135
127
|
|
data/lib/mongoid/components.rb
CHANGED
@@ -5,20 +5,19 @@ module Mongoid #:nodoc
|
|
5
5
|
base.class_eval do
|
6
6
|
# All modules that a +Document+ is composed of are defined in this
|
7
7
|
# module, to keep the document class from getting too cluttered.
|
8
|
-
include Associations
|
9
|
-
include Attributes
|
10
|
-
include
|
11
|
-
include
|
12
|
-
include
|
13
|
-
include
|
14
|
-
include
|
15
|
-
include
|
16
|
-
include
|
17
|
-
include Memoization
|
8
|
+
include Mongoid::Associations
|
9
|
+
include Mongoid::Attributes
|
10
|
+
include Mongoid::Callbacks
|
11
|
+
include Mongoid::Commands
|
12
|
+
include Mongoid::Extras
|
13
|
+
include Mongoid::Fields
|
14
|
+
include Mongoid::Indexes
|
15
|
+
include Mongoid::Matchers
|
16
|
+
include Mongoid::Memoization
|
18
17
|
include Observable
|
19
18
|
include Validatable
|
20
|
-
extend Finders
|
21
|
-
extend NamedScope
|
19
|
+
extend Mongoid::Finders
|
20
|
+
extend Mongoid::NamedScope
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
@@ -5,7 +5,7 @@ module Mongoid #:nodoc:
|
|
5
5
|
include Ids, Paging
|
6
6
|
attr_reader :criteria
|
7
7
|
|
8
|
-
delegate :first, :last, :to => :execute
|
8
|
+
delegate :blank?, :empty?, :first, :last, :to => :execute
|
9
9
|
delegate :documents, :options, :selector, :to => :criteria
|
10
10
|
|
11
11
|
# Return aggregation counts of the grouped documents. This will count by
|
@@ -25,16 +25,6 @@ module Mongoid #:nodoc:
|
|
25
25
|
@count ||= documents.size
|
26
26
|
end
|
27
27
|
|
28
|
-
# Groups the documents by the first field supplied in the field options.
|
29
|
-
#
|
30
|
-
# Returns:
|
31
|
-
#
|
32
|
-
# A +Hash+ with field values as keys, arrays of documents as values.
|
33
|
-
def group
|
34
|
-
field = options[:fields].first
|
35
|
-
documents.group_by { |doc| doc.send(field) }
|
36
|
-
end
|
37
|
-
|
38
28
|
# Enumerable implementation of execute. Returns matching documents for
|
39
29
|
# the selector, and adds options if supplied.
|
40
30
|
#
|
@@ -45,6 +35,16 @@ module Mongoid #:nodoc:
|
|
45
35
|
limit(documents.select { |document| document.matches?(selector) })
|
46
36
|
end
|
47
37
|
|
38
|
+
# Groups the documents by the first field supplied in the field options.
|
39
|
+
#
|
40
|
+
# Returns:
|
41
|
+
#
|
42
|
+
# A +Hash+ with field values as keys, arrays of documents as values.
|
43
|
+
def group
|
44
|
+
field = options[:fields].first
|
45
|
+
documents.group_by { |doc| doc.send(field) }
|
46
|
+
end
|
47
|
+
|
48
48
|
# Create the new enumerable context. This will need the selector and
|
49
49
|
# options from a +Criteria+ and a documents array that is the underlying
|
50
50
|
# array of embedded documents from a has many association.
|
@@ -56,6 +56,16 @@ module Mongoid #:nodoc:
|
|
56
56
|
@criteria = criteria
|
57
57
|
end
|
58
58
|
|
59
|
+
# Iterate over each +Document+ in the results. This can take an optional
|
60
|
+
# block to pass to each argument in the results.
|
61
|
+
#
|
62
|
+
# Example:
|
63
|
+
#
|
64
|
+
# <tt>context.iterate { |doc| p doc }</tt>
|
65
|
+
def iterate(&block)
|
66
|
+
execute.each(&block)
|
67
|
+
end
|
68
|
+
|
59
69
|
# Get the largest value for the field in all the documents.
|
60
70
|
#
|
61
71
|
# Returns:
|
@@ -23,6 +23,18 @@ module Mongoid #:nodoc:
|
|
23
23
|
klass.collection.group(options[:fields], selector, { :count => 0 }, Javascript.aggregate, true)
|
24
24
|
end
|
25
25
|
|
26
|
+
# Determine if the context is empty or blank given the criteria. Will
|
27
|
+
# perform a quick has_one asking only for the id.
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
#
|
31
|
+
# <tt>context.blank?</tt>
|
32
|
+
def blank?
|
33
|
+
klass.collection.find_one(selector, { :fields => [ :_id ] }).nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
alias :empty? :blank?
|
37
|
+
|
26
38
|
# Get the count of matching documents in the database for the context.
|
27
39
|
#
|
28
40
|
# Example:
|
@@ -43,7 +55,7 @@ module Mongoid #:nodoc:
|
|
43
55
|
#
|
44
56
|
# Example:
|
45
57
|
#
|
46
|
-
# <tt>
|
58
|
+
# <tt>context.execute</tt>
|
47
59
|
#
|
48
60
|
# Returns:
|
49
61
|
#
|
@@ -100,6 +112,19 @@ module Mongoid #:nodoc:
|
|
100
112
|
criteria.cache if klass.cached?
|
101
113
|
end
|
102
114
|
|
115
|
+
# Iterate over each +Document+ in the results. This can take an optional
|
116
|
+
# block to pass to each argument in the results.
|
117
|
+
#
|
118
|
+
# Example:
|
119
|
+
#
|
120
|
+
# <tt>context.iterate { |doc| p doc }</tt>
|
121
|
+
def iterate(&block)
|
122
|
+
return caching(&block) if criteria.cached?
|
123
|
+
if block_given?
|
124
|
+
execute.each { |doc| yield doc }
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
103
128
|
# Return the last result for the +Context+. Essentially does a find_one on
|
104
129
|
# the collection with the sorting reversed. If no sorting parameters have
|
105
130
|
# been provided it will default to ids.
|
@@ -214,6 +239,20 @@ module Mongoid #:nodoc:
|
|
214
239
|
options.dup
|
215
240
|
end
|
216
241
|
|
242
|
+
protected
|
243
|
+
|
244
|
+
# Iterate over each +Document+ in the results and cache the collection.
|
245
|
+
def caching(&block)
|
246
|
+
if defined? @collection
|
247
|
+
@collection.each(&block)
|
248
|
+
else
|
249
|
+
@collection = []
|
250
|
+
execute.each do |doc|
|
251
|
+
@collection << doc
|
252
|
+
yield doc if block_given?
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
217
256
|
end
|
218
257
|
end
|
219
258
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -31,7 +31,9 @@ module Mongoid #:nodoc:
|
|
31
31
|
|
32
32
|
delegate \
|
33
33
|
:aggregate,
|
34
|
+
:blank?,
|
34
35
|
:count,
|
36
|
+
:empty?,
|
35
37
|
:execute,
|
36
38
|
:first,
|
37
39
|
:group,
|
@@ -76,17 +78,6 @@ module Mongoid #:nodoc:
|
|
76
78
|
end
|
77
79
|
end
|
78
80
|
|
79
|
-
# Returns true if the criteria is empty.
|
80
|
-
#
|
81
|
-
# Example:
|
82
|
-
#
|
83
|
-
# <tt>criteria.blank?</tt>
|
84
|
-
def blank?
|
85
|
-
count < 1
|
86
|
-
end
|
87
|
-
|
88
|
-
alias :empty? :blank?
|
89
|
-
|
90
81
|
# Return or create the context in which this criteria should be executed.
|
91
82
|
#
|
92
83
|
# This will return an Enumerable context if the class is embedded,
|
@@ -102,10 +93,7 @@ module Mongoid #:nodoc:
|
|
102
93
|
#
|
103
94
|
# <tt>criteria.each { |doc| p doc }</tt>
|
104
95
|
def each(&block)
|
105
|
-
|
106
|
-
if block_given?
|
107
|
-
execute.each { |doc| yield doc }
|
108
|
-
end
|
96
|
+
context.iterate(&block)
|
109
97
|
self
|
110
98
|
end
|
111
99
|
|
@@ -213,20 +201,6 @@ module Mongoid #:nodoc:
|
|
213
201
|
|
214
202
|
protected
|
215
203
|
|
216
|
-
# Iterate over each +Document+ in the results and cache the collection.
|
217
|
-
def caching(&block)
|
218
|
-
@collection ||= execute
|
219
|
-
if block_given?
|
220
|
-
docs = []
|
221
|
-
@collection.each do |doc|
|
222
|
-
docs << doc
|
223
|
-
yield doc
|
224
|
-
end
|
225
|
-
@collection = docs
|
226
|
-
end
|
227
|
-
self
|
228
|
-
end
|
229
|
-
|
230
204
|
# Filters the unused options out of the options +Hash+. Currently this
|
231
205
|
# takes into account the "page" and "per_page" options that would be passed
|
232
206
|
# in if using will_paginate.
|
@@ -22,6 +22,7 @@ module Mongoid #:nodoc:
|
|
22
22
|
def all(attributes = {})
|
23
23
|
update_selector(attributes, "$all")
|
24
24
|
end
|
25
|
+
alias :all_in :all
|
25
26
|
|
26
27
|
# Adds a criterion to the +Criteria+ that specifies values that must
|
27
28
|
# be matched in order to return results. This is similar to a SQL "WHERE"
|
@@ -61,7 +62,7 @@ module Mongoid #:nodoc:
|
|
61
62
|
def in(attributes = {})
|
62
63
|
update_selector(attributes, "$in")
|
63
64
|
end
|
64
|
-
alias any_in in
|
65
|
+
alias :any_in :in
|
65
66
|
|
66
67
|
# Adds a criterion to the +Criteria+ that specifies values that must
|
67
68
|
# be matched in order to return results. This is similar to a SQL "WHERE"
|
data/lib/mongoid/document.rb
CHANGED
@@ -78,8 +78,6 @@ module Mongoid #:nodoc:
|
|
78
78
|
#
|
79
79
|
# class Person
|
80
80
|
# include Mongoid::Document
|
81
|
-
# field :first_name
|
82
|
-
# field :last_name
|
83
81
|
# key :first_name, :last_name
|
84
82
|
# end
|
85
83
|
def key(*fields)
|
@@ -132,10 +130,6 @@ module Mongoid #:nodoc:
|
|
132
130
|
#
|
133
131
|
# parent: The +Document+ to assimilate with.
|
134
132
|
# options: The association +Options+ for the child.
|
135
|
-
#
|
136
|
-
# Example:
|
137
|
-
#
|
138
|
-
# <tt>name.assimilate(person, options)</tt>
|
139
133
|
def assimilate(parent, options)
|
140
134
|
parentize(parent, options.name); notify; self
|
141
135
|
end
|
@@ -193,6 +187,11 @@ module Mongoid #:nodoc:
|
|
193
187
|
@new_record = saved
|
194
188
|
end
|
195
189
|
|
190
|
+
# Checks if the document has been saved to the database.
|
191
|
+
def persisted?
|
192
|
+
!new_record?
|
193
|
+
end
|
194
|
+
|
196
195
|
# Set the changed state of the +Document+ then notify observers that it has changed.
|
197
196
|
#
|
198
197
|
# Example:
|