mongoid 2.2.6 → 2.3.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/CHANGELOG.md +2 -858
- data/Rakefile +2 -5
- data/lib/mongoid.rb +1 -1
- data/lib/mongoid/attributes.rb +68 -18
- data/lib/mongoid/attributes/processing.rb +4 -3
- data/lib/mongoid/callbacks.rb +102 -0
- data/lib/mongoid/collection.rb +1 -1
- data/lib/mongoid/components.rb +2 -1
- data/lib/mongoid/contexts/enumerable.rb +0 -24
- data/lib/mongoid/contexts/mongo.rb +2 -2
- data/lib/mongoid/copyable.rb +3 -1
- data/lib/mongoid/criteria.rb +18 -10
- data/lib/mongoid/criterion/complex.rb +11 -0
- data/lib/mongoid/criterion/inclusion.rb +38 -7
- data/lib/mongoid/criterion/optional.rb +2 -7
- data/lib/mongoid/criterion/selector.rb +1 -0
- data/lib/mongoid/dirty.rb +19 -0
- data/lib/mongoid/document.rb +16 -12
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +1 -1
- data/lib/mongoid/extensions/object/checks.rb +4 -1
- data/lib/mongoid/extensions/object_id/conversions.rb +4 -2
- data/lib/mongoid/extensions/string/inflections.rb +2 -2
- data/lib/mongoid/factory.rb +7 -2
- data/lib/mongoid/fields.rb +4 -10
- data/lib/mongoid/fields/serializable.rb +18 -2
- data/lib/mongoid/fields/serializable/integer.rb +17 -5
- data/lib/mongoid/fields/serializable/localized.rb +41 -0
- data/lib/mongoid/finders.rb +5 -4
- data/lib/mongoid/hierarchy.rb +87 -84
- data/lib/mongoid/identity.rb +4 -2
- data/lib/mongoid/keys.rb +2 -1
- data/lib/mongoid/logger.rb +1 -7
- data/lib/mongoid/matchers/and.rb +30 -0
- data/lib/mongoid/matchers/in.rb +1 -1
- data/lib/mongoid/matchers/nin.rb +1 -1
- data/lib/mongoid/matchers/strategies.rb +6 -4
- data/lib/mongoid/multi_parameter_attributes.rb +3 -2
- data/lib/mongoid/named_scope.rb +3 -13
- data/lib/mongoid/nested_attributes.rb +1 -1
- data/lib/mongoid/paranoia.rb +2 -3
- data/lib/mongoid/persistence.rb +9 -5
- data/lib/mongoid/persistence/atomic/operation.rb +1 -1
- data/lib/mongoid/persistence/deletion.rb +1 -1
- data/lib/mongoid/persistence/insertion.rb +1 -1
- data/lib/mongoid/persistence/modification.rb +1 -1
- data/lib/mongoid/railtie.rb +1 -1
- data/lib/mongoid/railties/database.rake +9 -1
- data/lib/mongoid/relations.rb +1 -0
- data/lib/mongoid/relations/accessors.rb +1 -1
- data/lib/mongoid/relations/builders.rb +6 -4
- data/lib/mongoid/relations/builders/referenced/many.rb +1 -23
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
- data/lib/mongoid/relations/cascading.rb +5 -3
- data/lib/mongoid/relations/conversions.rb +35 -0
- data/lib/mongoid/relations/embedded/atomic.rb +3 -3
- data/lib/mongoid/relations/embedded/in.rb +1 -1
- data/lib/mongoid/relations/embedded/many.rb +16 -13
- data/lib/mongoid/relations/embedded/one.rb +3 -3
- data/lib/mongoid/relations/metadata.rb +19 -15
- data/lib/mongoid/relations/proxy.rb +4 -5
- data/lib/mongoid/relations/referenced/in.rb +1 -1
- data/lib/mongoid/relations/referenced/many.rb +12 -31
- data/lib/mongoid/relations/referenced/many_to_many.rb +4 -5
- data/lib/mongoid/relations/referenced/one.rb +6 -8
- data/lib/mongoid/relations/synchronization.rb +3 -5
- data/lib/mongoid/safety.rb +34 -4
- data/lib/mongoid/serialization.rb +20 -6
- data/lib/mongoid/threaded.rb +47 -0
- data/lib/mongoid/timestamps.rb +1 -0
- data/lib/mongoid/timestamps/created.rb +1 -8
- data/lib/mongoid/timestamps/timeless.rb +50 -0
- data/lib/mongoid/timestamps/updated.rb +2 -9
- data/lib/mongoid/validations.rb +0 -2
- data/lib/mongoid/validations/associated.rb +1 -2
- data/lib/mongoid/validations/uniqueness.rb +89 -36
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +5 -6
- data/lib/rails/generators/mongoid_generator.rb +1 -1
- data/lib/rails/mongoid.rb +14 -5
- metadata +27 -23
data/Rakefile
CHANGED
@@ -24,10 +24,6 @@ task :release => :build do
|
|
24
24
|
system "gem push mongoid-#{Mongoid::VERSION}.gem"
|
25
25
|
end
|
26
26
|
|
27
|
-
RSpec::Core::RakeTask.new(:spec) do |spec|
|
28
|
-
spec.pattern = "spec/**/*_spec.rb"
|
29
|
-
end
|
30
|
-
|
31
27
|
RSpec::Core::RakeTask.new("spec:unit") do |spec|
|
32
28
|
spec.pattern = "spec/unit/**/*_spec.rb"
|
33
29
|
end
|
@@ -49,4 +45,5 @@ RDoc::Task.new do |rdoc|
|
|
49
45
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
50
46
|
end
|
51
47
|
|
52
|
-
task :
|
48
|
+
task :spec => [ "spec:functional", "spec:unit" ]
|
49
|
+
task :default => :spec
|
data/lib/mongoid.rb
CHANGED
@@ -94,7 +94,7 @@ I18n.load_path << File.join(File.dirname(__FILE__), "config", "locales", "en.yml
|
|
94
94
|
module Mongoid #:nodoc
|
95
95
|
extend self
|
96
96
|
|
97
|
-
MONGODB_VERSION = "
|
97
|
+
MONGODB_VERSION = "2.0.0"
|
98
98
|
|
99
99
|
# Sets the Mongoid configuration options. Best used by passing a block.
|
100
100
|
#
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -6,6 +6,7 @@ module Mongoid #:nodoc:
|
|
6
6
|
# This module contains the logic for handling the internal attributes hash,
|
7
7
|
# and how to get and set values.
|
8
8
|
module Attributes
|
9
|
+
extend ActiveSupport::Concern
|
9
10
|
include Processing
|
10
11
|
|
11
12
|
attr_reader :attributes
|
@@ -56,7 +57,7 @@ module Mongoid #:nodoc:
|
|
56
57
|
#
|
57
58
|
# @since 1.0.0
|
58
59
|
def remove_attribute(name)
|
59
|
-
|
60
|
+
_assigning do
|
60
61
|
access = name.to_s
|
61
62
|
attribute_will_change!(access)
|
62
63
|
attributes.delete(access)
|
@@ -95,18 +96,46 @@ module Mongoid #:nodoc:
|
|
95
96
|
#
|
96
97
|
# @since 1.0.0
|
97
98
|
def write_attribute(name, value)
|
98
|
-
|
99
|
+
_assigning do
|
99
100
|
access = name.to_s
|
101
|
+
localized = fields[access].try(:localized?)
|
100
102
|
typed_value_for(access, value).tap do |value|
|
101
103
|
unless attributes[access] == value || attribute_changed?(access)
|
102
104
|
attribute_will_change!(access)
|
103
105
|
end
|
104
|
-
|
106
|
+
if localized
|
107
|
+
(attributes[access] ||= {}).merge!(value)
|
108
|
+
else
|
109
|
+
attributes[access] = value
|
110
|
+
end
|
105
111
|
end
|
106
112
|
end
|
107
113
|
end
|
108
114
|
alias :[]= :write_attribute
|
109
115
|
|
116
|
+
# Allows you to set all the attributes for a particular mass-assignment security role
|
117
|
+
# by passing in a hash of attributes with keys matching the attribute names
|
118
|
+
# (which again matches the column names) and the role name using the :as option.
|
119
|
+
# To bypass mass-assignment security you can use the :without_protection => true option.
|
120
|
+
#
|
121
|
+
# @example Assign the attributes.
|
122
|
+
# person.assign_attributes(:title => "Mr.")
|
123
|
+
#
|
124
|
+
# @example Assign the attributes (with a role).
|
125
|
+
# person.assign_attributes({ :title => "Mr." }, :as => :admin)
|
126
|
+
#
|
127
|
+
# @param [ Hash ] attrs The new attributes to set.
|
128
|
+
# @param [ Hash ] options Supported options: :without_protection, :as
|
129
|
+
#
|
130
|
+
# @since 2.2.1
|
131
|
+
def assign_attributes(attrs = nil, options = {})
|
132
|
+
_assigning do
|
133
|
+
process(attrs, options[:as] || :default, !options[:without_protection]) do |document|
|
134
|
+
document.identify if new? && id.blank?
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
110
139
|
# Writes the supplied attributes hash to the document. This will only
|
111
140
|
# overwrite existing attributes if they are present in the new +Hash+, all
|
112
141
|
# others will be preserved.
|
@@ -122,11 +151,7 @@ module Mongoid #:nodoc:
|
|
122
151
|
#
|
123
152
|
# @since 1.0.0
|
124
153
|
def write_attributes(attrs = nil, guard_protected_attributes = true)
|
125
|
-
|
126
|
-
process(attrs, guard_protected_attributes) do |document|
|
127
|
-
document.identify if new? && id.blank?
|
128
|
-
end
|
129
|
-
end
|
154
|
+
assign_attributes(attrs, :without_protection => !guard_protected_attributes)
|
130
155
|
end
|
131
156
|
alias :attributes= :write_attributes
|
132
157
|
|
@@ -135,18 +160,16 @@ module Mongoid #:nodoc:
|
|
135
160
|
# Set any missing default values in the attributes.
|
136
161
|
#
|
137
162
|
# @example Get the raw attributes after defaults have been applied.
|
138
|
-
# person.
|
163
|
+
# person.apply_defaults
|
139
164
|
#
|
140
165
|
# @return [ Hash ] The raw attributes.
|
141
166
|
#
|
142
167
|
# @since 2.0.0.rc.8
|
143
|
-
def
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
attrs[name] = field.eval_default(self)
|
149
|
-
end
|
168
|
+
def apply_defaults
|
169
|
+
defaults.each do |name|
|
170
|
+
unless attributes.has_key?(name)
|
171
|
+
if field = fields[name]
|
172
|
+
attributes[name] = field.eval_default(self)
|
150
173
|
end
|
151
174
|
end
|
152
175
|
end
|
@@ -157,14 +180,14 @@ module Mongoid #:nodoc:
|
|
157
180
|
# be in a valid state.
|
158
181
|
#
|
159
182
|
# @example Execute the assignment.
|
160
|
-
#
|
183
|
+
# _assigning do
|
161
184
|
# person.attributes = { :addresses => [ address ] }
|
162
185
|
# end
|
163
186
|
#
|
164
187
|
# @return [ Object ] The yielded value.
|
165
188
|
#
|
166
189
|
# @since 2.2.0
|
167
|
-
def
|
190
|
+
def _assigning
|
168
191
|
begin
|
169
192
|
Threaded.begin_assign
|
170
193
|
yield
|
@@ -201,5 +224,32 @@ module Mongoid #:nodoc:
|
|
201
224
|
def typed_value_for(key, value)
|
202
225
|
fields.has_key?(key) ? fields[key].serialize(value) : value
|
203
226
|
end
|
227
|
+
|
228
|
+
module ClassMethods #:nodoc:
|
229
|
+
|
230
|
+
# Alias the provided name to the original field. This will provide an
|
231
|
+
# aliased getter, setter, existance check, and all dirty attribute
|
232
|
+
# methods.
|
233
|
+
#
|
234
|
+
# @example Alias the attribute.
|
235
|
+
# class Product
|
236
|
+
# include Mongoid::Document
|
237
|
+
# field :price, :type => Float
|
238
|
+
# alias_attribute :cost, :price
|
239
|
+
# end
|
240
|
+
#
|
241
|
+
# @param [ Symbol ] name The new name.
|
242
|
+
# @param [ Symbol ] original The original name.
|
243
|
+
#
|
244
|
+
# @since 2.3.0
|
245
|
+
def alias_attribute(name, original)
|
246
|
+
class_eval <<-RUBY
|
247
|
+
alias :#{name} :#{original}
|
248
|
+
alias :#{name}= :#{original}=
|
249
|
+
alias :#{name}? :#{original}?
|
250
|
+
RUBY
|
251
|
+
super
|
252
|
+
end
|
253
|
+
end
|
204
254
|
end
|
205
255
|
end
|
@@ -14,12 +14,13 @@ module Mongoid #:nodoc:
|
|
14
14
|
# person.process(:title => "sir", :age => 40)
|
15
15
|
#
|
16
16
|
# @param [ Hash ] attrs The attributes to set.
|
17
|
+
# @param [ Symbol ] role A role for scoped mass assignment.
|
17
18
|
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
18
19
|
#
|
19
20
|
# @since 2.0.0.rc.7
|
20
|
-
def process(attrs = nil, guard_protected_attributes = true)
|
21
|
+
def process(attrs = nil, role = :default, guard_protected_attributes = true)
|
21
22
|
attrs ||= {}
|
22
|
-
attrs = sanitize_for_mass_assignment(attrs) if guard_protected_attributes
|
23
|
+
attrs = sanitize_for_mass_assignment(attrs, role) if guard_protected_attributes
|
23
24
|
attrs.each_pair do |key, value|
|
24
25
|
next if pending_attribute?(key, value)
|
25
26
|
process_attribute(key, value)
|
@@ -37,7 +38,7 @@ module Mongoid #:nodoc:
|
|
37
38
|
# @example Is the attribute pending?
|
38
39
|
# document.pending_attribute?(:name, "Durran")
|
39
40
|
#
|
40
|
-
# @param [
|
41
|
+
# @param [ Symbol ] key The name of the attribute.
|
41
42
|
# @param [ Object ] value The value of the attribute.
|
42
43
|
#
|
43
44
|
# @return [ true, false ] True if pending, false if not.
|
data/lib/mongoid/callbacks.rb
CHANGED
@@ -21,5 +21,107 @@ module Mongoid #:nodoc:
|
|
21
21
|
define_model_callbacks :initialize, :only => :after
|
22
22
|
define_model_callbacks :create, :destroy, :save, :update
|
23
23
|
end
|
24
|
+
|
25
|
+
# Run the callbacks for the document. This overrides active support's
|
26
|
+
# functionality to cascade callbacks to embedded documents that have been
|
27
|
+
# flagged as such.
|
28
|
+
#
|
29
|
+
# @example Run the callbacks.
|
30
|
+
# run_callbacks :save do
|
31
|
+
# save!
|
32
|
+
# end
|
33
|
+
#
|
34
|
+
# @param [ Symbol ] kind The type of callback to execute.
|
35
|
+
# @param [ Array ] *args Any options.
|
36
|
+
#
|
37
|
+
# @return [ Document ] The document
|
38
|
+
#
|
39
|
+
# @since 2.3.0
|
40
|
+
def run_callbacks(kind, *args, &block)
|
41
|
+
run_cascading_callbacks(cascadable_children(kind), kind, *args) do
|
42
|
+
super(kind, *args, &block)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
# Execute the callbacks, including all children that have cascade callbacks
|
49
|
+
# set to true.
|
50
|
+
#
|
51
|
+
# @example Run the cascading callbacks.
|
52
|
+
# document.run_cascading_callbacks([], :update)
|
53
|
+
#
|
54
|
+
# @param [ Array<Document> ] children The cascading children.
|
55
|
+
# @param [ Symbol ] kind The callback type.
|
56
|
+
# @param [ Array ] args The options.
|
57
|
+
#
|
58
|
+
# @since 2.3.0
|
59
|
+
def run_cascading_callbacks(children, kind, *args, &block)
|
60
|
+
if child = children.pop
|
61
|
+
run_cascading_callbacks(children, kind, *args) do
|
62
|
+
child.run_callbacks(child_callback_type(kind, child), *args) do
|
63
|
+
block.call
|
64
|
+
end
|
65
|
+
end
|
66
|
+
else
|
67
|
+
block.call
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get all the child embedded documents that are flagged as cascadable.
|
72
|
+
#
|
73
|
+
# @example Get all the cascading children.
|
74
|
+
# document.cascadable_children(:update)
|
75
|
+
#
|
76
|
+
# @param [ Symbol ] kind The type of callback.
|
77
|
+
#
|
78
|
+
# @return [ Array<Document> ] The children.
|
79
|
+
#
|
80
|
+
# @since 2.3.0
|
81
|
+
def cascadable_children(kind)
|
82
|
+
[].tap do |children|
|
83
|
+
relations.each_pair do |name, metadata|
|
84
|
+
next unless metadata.cascading_callbacks?
|
85
|
+
child = send(name)
|
86
|
+
Array.wrap(child).each do |doc|
|
87
|
+
children.push(doc) if cascadable_child?(kind, doc)
|
88
|
+
children.concat(doc.send(:cascadable_children, kind))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Determine if the child should fire the callback.
|
95
|
+
#
|
96
|
+
# @example Should the child fire the callback?
|
97
|
+
# document.cascadable_child?(:update, doc)
|
98
|
+
#
|
99
|
+
# @param [ Symbol ] kind The type of callback.
|
100
|
+
# @param [ Document ] child The child document.
|
101
|
+
#
|
102
|
+
# @return [ true, false ] If the child should fire the callback.
|
103
|
+
#
|
104
|
+
# @since 2.3.0
|
105
|
+
def cascadable_child?(kind, child)
|
106
|
+
[ :create, :destroy ].include?(kind) || child.changed? || child.new_record?
|
107
|
+
end
|
108
|
+
|
109
|
+
# Get the name of the callback that the child should fire. This changes
|
110
|
+
# depending on whether or not the child is new. A persisted parent with a
|
111
|
+
# new child would fire :update from the parent, but needs to fire :create
|
112
|
+
# on the child.
|
113
|
+
#
|
114
|
+
# @example Get the callback type.
|
115
|
+
# document.child_callback_type(:update, doc)
|
116
|
+
#
|
117
|
+
# @param [ Symbol ] kind The type of callback.
|
118
|
+
# @param [ Document ] child The child document
|
119
|
+
#
|
120
|
+
# @return [ Symbol ] The name of the callback.
|
121
|
+
#
|
122
|
+
# @since 2.3.0
|
123
|
+
def child_callback_type(kind, child)
|
124
|
+
kind == :update && child.new_record? ? :create : kind
|
125
|
+
end
|
24
126
|
end
|
25
127
|
end
|
data/lib/mongoid/collection.rb
CHANGED
@@ -142,7 +142,7 @@ module Mongoid #:nodoc
|
|
142
142
|
#
|
143
143
|
# @since 2.0.0
|
144
144
|
def update(selector, document, options = {})
|
145
|
-
updater = Threaded.update_consumer(
|
145
|
+
updater = Threaded.update_consumer(klass)
|
146
146
|
if updater
|
147
147
|
updater.consume(selector, document, options)
|
148
148
|
else
|
data/lib/mongoid/components.rb
CHANGED
@@ -17,11 +17,11 @@ module Mongoid #:nodoc
|
|
17
17
|
include ActiveModel::Serializers::JSON
|
18
18
|
include ActiveModel::Serializers::Xml
|
19
19
|
include Mongoid::Atomic
|
20
|
+
include Mongoid::Dirty
|
20
21
|
include Mongoid::Attributes
|
21
22
|
include Mongoid::Collections
|
22
23
|
include Mongoid::Copyable
|
23
24
|
include Mongoid::DefaultScope
|
24
|
-
include Mongoid::Dirty
|
25
25
|
include Mongoid::Extras
|
26
26
|
include Mongoid::Fields
|
27
27
|
include Mongoid::Hierarchy
|
@@ -38,6 +38,7 @@ module Mongoid #:nodoc
|
|
38
38
|
include Mongoid::Serialization
|
39
39
|
include Mongoid::Sharding
|
40
40
|
include Mongoid::State
|
41
|
+
include Mongoid::Timestamps::Timeless
|
41
42
|
include Mongoid::Validations
|
42
43
|
include Mongoid::Callbacks
|
43
44
|
include Mongoid::MultiDatabase
|
@@ -210,18 +210,6 @@ module Mongoid #:nodoc:
|
|
210
210
|
|
211
211
|
protected
|
212
212
|
|
213
|
-
# Get the root class collection name.
|
214
|
-
#
|
215
|
-
# @example Get the root class collection name.
|
216
|
-
# context.collection_name
|
217
|
-
#
|
218
|
-
# @return [ String ] The name of the collection.
|
219
|
-
#
|
220
|
-
# @since 2.4.3
|
221
|
-
def collection_name
|
222
|
-
root ? root.collection_name : nil
|
223
|
-
end
|
224
|
-
|
225
213
|
# Filters the documents against the criteria's selector
|
226
214
|
#
|
227
215
|
# @example Filter the documents.
|
@@ -263,22 +251,10 @@ module Mongoid #:nodoc:
|
|
263
251
|
documents
|
264
252
|
end
|
265
253
|
|
266
|
-
# Get the root document for the enumerable.
|
267
|
-
#
|
268
|
-
# @example Get the root document.
|
269
|
-
# context.root
|
270
|
-
#
|
271
|
-
# @return [ Document ] The root.
|
272
254
|
def root
|
273
255
|
@root ||= documents.first.try(:_root)
|
274
256
|
end
|
275
257
|
|
276
|
-
# Get the root class for the enumerable.
|
277
|
-
#
|
278
|
-
# @example Get the root class.
|
279
|
-
# context.root_class
|
280
|
-
#
|
281
|
-
# @return [ Class ] The root class.
|
282
258
|
def root_class
|
283
259
|
@root_class ||= root ? root.class : nil
|
284
260
|
end
|
@@ -330,7 +330,7 @@ module Mongoid #:nodoc:
|
|
330
330
|
{ "$set" => attributes },
|
331
331
|
Safety.merge_safety_options(:multi => true)
|
332
332
|
).tap do
|
333
|
-
Threaded.
|
333
|
+
Threaded.clear_options!
|
334
334
|
end
|
335
335
|
end
|
336
336
|
alias :update :update_all
|
@@ -371,7 +371,7 @@ module Mongoid #:nodoc:
|
|
371
371
|
:reduce => reduce.gsub("[field]", field)
|
372
372
|
)
|
373
373
|
value = collection.empty? ? nil : collection.first[start.to_s]
|
374
|
-
value
|
374
|
+
value && value.try(:nan?) ? nil : value
|
375
375
|
end
|
376
376
|
|
377
377
|
# Filters the field list. If no fields have been supplied, then it will be
|
data/lib/mongoid/copyable.rb
CHANGED
@@ -38,7 +38,9 @@ module Mongoid #:nodoc:
|
|
38
38
|
instance_variable_set(name, value ? value.dup : nil)
|
39
39
|
end
|
40
40
|
attributes.delete("_id")
|
41
|
-
attributes.delete("versions")
|
41
|
+
if attributes.delete("versions")
|
42
|
+
attributes["version"] = 1
|
43
|
+
end
|
42
44
|
@new_record = true
|
43
45
|
identify
|
44
46
|
end
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -153,6 +153,19 @@ module Mongoid #:nodoc:
|
|
153
153
|
context.count > 0
|
154
154
|
end
|
155
155
|
|
156
|
+
# Extract a single id from the provided criteria. Could be in an $and
|
157
|
+
# query or a straight _id query.
|
158
|
+
#
|
159
|
+
# @example Extract the id.
|
160
|
+
# criteria.extract_id
|
161
|
+
#
|
162
|
+
# @return [ Object ] The id.
|
163
|
+
#
|
164
|
+
# @since 2.3.0
|
165
|
+
def extract_id
|
166
|
+
selector[:_id]
|
167
|
+
end
|
168
|
+
|
156
169
|
# When freezing a criteria we need to initialize the context first
|
157
170
|
# otherwise the setting of the context on attempted iteration will raise a
|
158
171
|
# runtime error.
|
@@ -383,19 +396,14 @@ module Mongoid #:nodoc:
|
|
383
396
|
clone.tap do |crit|
|
384
397
|
converted = BSON::ObjectId.convert(klass, attributes || {})
|
385
398
|
converted.each_pair do |key, value|
|
386
|
-
|
387
|
-
unless existing
|
399
|
+
unless crit.selector[key]
|
388
400
|
crit.selector[key] = { operator => value }
|
389
401
|
else
|
390
|
-
if
|
391
|
-
|
392
|
-
|
393
|
-
crit.selector[key] = { operator => new_value }
|
394
|
-
else
|
395
|
-
crit.selector[key][operator] = value
|
396
|
-
end
|
402
|
+
if crit.selector[key].has_key?(operator)
|
403
|
+
new_value = crit.selector[key].values.first.send(combine, value)
|
404
|
+
crit.selector[key] = { operator => new_value }
|
397
405
|
else
|
398
|
-
crit.selector[key] =
|
406
|
+
crit.selector[key][operator] = value
|
399
407
|
end
|
400
408
|
end
|
401
409
|
end
|