mongoid 3.0.23 → 3.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/CHANGELOG.md +253 -9
- data/LICENSE +1 -1
- data/README.md +4 -1
- data/lib/config/locales/en.yml +7 -6
- data/lib/mongoid.rb +18 -1
- data/lib/mongoid/atomic.rb +22 -20
- data/lib/mongoid/atomic/paths/embedded.rb +19 -5
- data/lib/mongoid/atomic/paths/root.rb +1 -1
- data/lib/mongoid/atomic/positionable.rb +73 -0
- data/lib/mongoid/attributes.rb +63 -1
- data/lib/mongoid/callbacks.rb +58 -4
- data/lib/mongoid/components.rb +8 -3
- data/lib/mongoid/config.rb +71 -23
- data/lib/mongoid/contextual.rb +2 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +27 -63
- data/lib/mongoid/contextual/atomic.rb +4 -3
- data/lib/mongoid/contextual/find_and_modify.rb +1 -1
- data/lib/mongoid/contextual/geo_near.rb +238 -0
- data/lib/mongoid/contextual/map_reduce.rb +12 -1
- data/lib/mongoid/contextual/memory.rb +36 -31
- data/lib/mongoid/contextual/mongo.rb +147 -91
- data/lib/mongoid/contextual/queryable.rb +25 -0
- data/lib/mongoid/copyable.rb +4 -1
- data/lib/mongoid/criteria.rb +23 -275
- data/lib/mongoid/criterion/findable.rb +179 -0
- data/lib/mongoid/criterion/modifiable.rb +191 -0
- data/lib/mongoid/criterion/scoping.rb +11 -6
- data/lib/mongoid/document.rb +7 -56
- data/lib/mongoid/equality.rb +66 -0
- data/lib/mongoid/errors/mongoid_error.rb +7 -3
- data/lib/mongoid/extensions/array.rb +13 -1
- data/lib/mongoid/extensions/date.rb +9 -2
- data/lib/mongoid/extensions/hash.rb +38 -2
- data/lib/mongoid/extensions/nil_class.rb +12 -0
- data/lib/mongoid/extensions/object.rb +24 -0
- data/lib/mongoid/extensions/string.rb +14 -2
- data/lib/mongoid/extensions/time.rb +4 -1
- data/lib/mongoid/fields.rb +49 -5
- data/lib/mongoid/fields/foreign_key.rb +12 -0
- data/lib/mongoid/fields/standard.rb +12 -0
- data/lib/mongoid/finders.rb +8 -0
- data/lib/mongoid/hierarchy.rb +19 -1
- data/lib/mongoid/indexes.rb +30 -4
- data/lib/mongoid/indexes/validators/options.rb +12 -2
- data/lib/mongoid/inspection.rb +2 -1
- data/lib/mongoid/matchers/strategies.rb +5 -5
- data/lib/mongoid/observer.rb +27 -36
- data/lib/mongoid/persistence.rb +42 -17
- data/lib/mongoid/persistence/atomic.rb +10 -5
- data/lib/mongoid/persistence/atomic/operation.rb +26 -9
- data/lib/mongoid/persistence/atomic/unset.rb +1 -1
- data/lib/mongoid/persistence/operations/embedded/insert.rb +5 -2
- data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -2
- data/lib/mongoid/persistence/operations/update.rb +7 -3
- data/lib/mongoid/railties/database.rake +12 -19
- data/lib/mongoid/relations.rb +2 -0
- data/lib/mongoid/relations/accessors.rb +30 -8
- data/lib/mongoid/relations/binding.rb +5 -1
- data/lib/mongoid/relations/bindings/referenced/in.rb +1 -1
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -3
- data/lib/mongoid/relations/counter_cache.rb +107 -0
- data/lib/mongoid/relations/embedded/batchable.rb +13 -4
- data/lib/mongoid/relations/embedded/many.rb +30 -1
- data/lib/mongoid/relations/macros.rb +2 -0
- data/lib/mongoid/relations/marshalable.rb +0 -1
- data/lib/mongoid/relations/metadata.rb +63 -11
- data/lib/mongoid/relations/options.rb +1 -0
- data/lib/mongoid/relations/proxy.rb +45 -2
- data/lib/mongoid/relations/referenced/in.rb +11 -2
- data/lib/mongoid/relations/referenced/many.rb +31 -3
- data/lib/mongoid/relations/referenced/many_to_many.rb +31 -3
- data/lib/mongoid/relations/referenced/one.rb +1 -1
- data/lib/mongoid/relations/targets/enumerable.rb +5 -1
- data/lib/mongoid/relations/touchable.rb +35 -6
- data/lib/mongoid/reloading.rb +5 -3
- data/lib/mongoid/scoping.rb +2 -2
- data/lib/mongoid/sessions.rb +57 -7
- data/lib/mongoid/sessions/factory.rb +22 -1
- data/lib/mongoid/threaded.rb +4 -30
- data/lib/mongoid/threaded/lifecycle.rb +12 -12
- data/lib/mongoid/timestamps.rb +1 -0
- data/lib/mongoid/timestamps/created.rb +2 -0
- data/lib/mongoid/timestamps/created/short.rb +19 -0
- data/lib/mongoid/timestamps/short.rb +10 -0
- data/lib/mongoid/timestamps/updated.rb +2 -0
- data/lib/mongoid/timestamps/updated/short.rb +19 -0
- data/lib/mongoid/validations.rb +2 -0
- data/lib/mongoid/validations/queryable.rb +2 -2
- data/lib/mongoid/validations/uniqueness.rb +1 -18
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/model/model_generator.rb +1 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +3 -0
- data/lib/rails/mongoid.rb +53 -29
- data/lib/support/ruby_version.rb +26 -0
- metadata +18 -7
@@ -16,7 +16,9 @@ module Mongoid
|
|
16
16
|
# false
|
17
17
|
# );
|
18
18
|
class Insert
|
19
|
-
include Insertion
|
19
|
+
include Insertion
|
20
|
+
include Operations
|
21
|
+
include Mongoid::Atomic::Positionable
|
20
22
|
|
21
23
|
# Insert the new document in the database. If the document's parent is a
|
22
24
|
# new record, we will call save on the parent, otherwise we will $push
|
@@ -32,7 +34,8 @@ module Mongoid
|
|
32
34
|
if parent.new_record?
|
33
35
|
parent.insert
|
34
36
|
else
|
35
|
-
|
37
|
+
selector = parent.atomic_selector
|
38
|
+
collection.find(selector).update(positionally(selector, inserts))
|
36
39
|
end
|
37
40
|
end
|
38
41
|
end
|
@@ -14,7 +14,9 @@ module Mongoid
|
|
14
14
|
# false
|
15
15
|
# );
|
16
16
|
class Remove
|
17
|
-
include Deletion
|
17
|
+
include Deletion
|
18
|
+
include Operations
|
19
|
+
include Mongoid::Atomic::Positionable
|
18
20
|
|
19
21
|
# Remove the document from the database. If the parent is a new record,
|
20
22
|
# it will get removed in Ruby only. If the parent is not a new record
|
@@ -29,7 +31,8 @@ module Mongoid
|
|
29
31
|
prepare do |doc|
|
30
32
|
parent.remove_child(doc) if notifying_parent?
|
31
33
|
if parent.persisted?
|
32
|
-
|
34
|
+
selector = parent.atomic_selector
|
35
|
+
collection.find(selector).update(positionally(selector, deletes))
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
@@ -30,7 +30,9 @@ module Mongoid
|
|
30
30
|
# );
|
31
31
|
#
|
32
32
|
class Update
|
33
|
-
include Modification
|
33
|
+
include Modification
|
34
|
+
include Operations
|
35
|
+
include Mongoid::Atomic::Positionable
|
34
36
|
|
35
37
|
# Persist the document that is to be updated to the database. This will
|
36
38
|
# only write changed fields via MongoDB's $set modifier operation.
|
@@ -42,9 +44,11 @@ module Mongoid
|
|
42
44
|
def persist
|
43
45
|
prepare do
|
44
46
|
unless updates.empty?
|
45
|
-
collection.find(selector).update(updates)
|
47
|
+
collection.find(selector).update(positionally(selector, updates))
|
46
48
|
conflicts.each_pair do |key, value|
|
47
|
-
collection.find(selector).update(
|
49
|
+
collection.find(selector).update(
|
50
|
+
positionally(selector, { key => value })
|
51
|
+
)
|
48
52
|
end
|
49
53
|
end
|
50
54
|
end
|
@@ -5,6 +5,11 @@ namespace :db do
|
|
5
5
|
task :drop => "mongoid:drop"
|
6
6
|
end
|
7
7
|
|
8
|
+
unless Rake::Task.task_defined?("db:purge")
|
9
|
+
desc "Drop all collections except the system collections"
|
10
|
+
task :purge => "mongoid:purge"
|
11
|
+
end
|
12
|
+
|
8
13
|
unless Rake::Task.task_defined?("db:seed")
|
9
14
|
# if another ORM has defined db:seed, don"t run it twice.
|
10
15
|
desc "Load the seed data from db/seeds.rb"
|
@@ -61,36 +66,24 @@ namespace :db do
|
|
61
66
|
end
|
62
67
|
|
63
68
|
namespace :mongoid do
|
64
|
-
|
65
69
|
desc "Create the indexes defined on your mongoid models"
|
66
70
|
task :create_indexes => :environment do
|
67
|
-
|
68
|
-
engine.paths["app/models"].expanded
|
69
|
-
end
|
70
|
-
root_models_paths = Rails.application.paths["app/models"]
|
71
|
-
models_paths = engines_models_paths.push(root_models_paths).flatten
|
72
|
-
|
73
|
-
models_paths.each do |path|
|
74
|
-
::Rails::Mongoid.create_indexes("#{path}/**/*.rb")
|
75
|
-
end
|
71
|
+
::Rails::Mongoid.create_indexes
|
76
72
|
end
|
77
73
|
|
78
74
|
desc "Remove the indexes defined on your mongoid models without questions!"
|
79
75
|
task :remove_indexes => :environment do
|
80
|
-
|
81
|
-
engine.paths["app/models"].expanded
|
82
|
-
end
|
83
|
-
root_models_paths = Rails.application.paths["app/models"]
|
84
|
-
models_paths = engines_models_paths.push(root_models_paths).flatten
|
85
|
-
|
86
|
-
models_paths.each do |path|
|
87
|
-
::Rails::Mongoid.remove_indexes("#{path}/**/*.rb")
|
88
|
-
end
|
76
|
+
::Rails::Mongoid.remove_indexes
|
89
77
|
end
|
90
78
|
|
91
79
|
desc "Drops the database for the current Rails.env"
|
92
80
|
task :drop => :environment do
|
93
81
|
::Mongoid::Sessions.default.drop
|
94
82
|
end
|
83
|
+
|
84
|
+
desc "Drop all collections except the system collections"
|
85
|
+
task :purge => :environment do
|
86
|
+
::Mongoid.purge!
|
87
|
+
end
|
95
88
|
end
|
96
89
|
end
|
data/lib/mongoid/relations.rb
CHANGED
@@ -4,6 +4,7 @@ require "mongoid/relations/auto_save"
|
|
4
4
|
require "mongoid/relations/cascading"
|
5
5
|
require "mongoid/relations/constraint"
|
6
6
|
require "mongoid/relations/conversions"
|
7
|
+
require "mongoid/relations/counter_cache"
|
7
8
|
require "mongoid/relations/cyclic"
|
8
9
|
require "mongoid/relations/proxy"
|
9
10
|
require "mongoid/relations/bindings"
|
@@ -43,6 +44,7 @@ module Mongoid
|
|
43
44
|
include Reflections
|
44
45
|
include Synchronization
|
45
46
|
include Touchable
|
47
|
+
include CounterCache
|
46
48
|
|
47
49
|
attr_accessor :metadata
|
48
50
|
|
@@ -113,11 +113,7 @@ module Mongoid
|
|
113
113
|
else
|
114
114
|
_building do
|
115
115
|
_loading do
|
116
|
-
|
117
|
-
# we want to avoid an extra database query when we know it is not
|
118
|
-
# necessary.
|
119
|
-
key = (new_record? && _binding?) ? nil : attributes[metadata.key]
|
120
|
-
__build__(name, key, metadata)
|
116
|
+
__build__(name, attributes[metadata.key], metadata)
|
121
117
|
end
|
122
118
|
end
|
123
119
|
end
|
@@ -128,6 +124,30 @@ module Mongoid
|
|
128
124
|
end
|
129
125
|
end
|
130
126
|
|
127
|
+
# @todo: Durran: Refactor before release, but this fixes the issue with
|
128
|
+
# the extra queries.
|
129
|
+
def get_relation_for_set(name, metadata, object)
|
130
|
+
variable = "@#{name}"
|
131
|
+
value = if instance_variable_defined?(variable)
|
132
|
+
instance_variable_get(variable)
|
133
|
+
else
|
134
|
+
_building do
|
135
|
+
_loading do
|
136
|
+
if needs_no_database_query?(object, metadata)
|
137
|
+
__build__(name, object, metadata)
|
138
|
+
else
|
139
|
+
__build__(name, attributes[metadata.key], metadata)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def needs_no_database_query?(object, metadata)
|
147
|
+
object.is_a?(Document) && !object.embedded? &&
|
148
|
+
object.id == attributes[metadata.key]
|
149
|
+
end
|
150
|
+
|
131
151
|
# Is the current code executing without autobuild functionality?
|
132
152
|
#
|
133
153
|
# @example Is autobuild disabled?
|
@@ -151,10 +171,10 @@ module Mongoid
|
|
151
171
|
#
|
152
172
|
# @since 3.0.0
|
153
173
|
def without_autobuild
|
154
|
-
Threaded.
|
174
|
+
Threaded.begin_execution("without_autobuild")
|
155
175
|
yield
|
156
176
|
ensure
|
157
|
-
Threaded.
|
177
|
+
Threaded.exit_execution("without_autobuild")
|
158
178
|
end
|
159
179
|
|
160
180
|
module ClassMethods
|
@@ -241,8 +261,10 @@ module Mongoid
|
|
241
261
|
def setter(name, metadata)
|
242
262
|
re_define_method("#{name}=") do |object|
|
243
263
|
without_autobuild do
|
244
|
-
if metadata.many?
|
264
|
+
if metadata.many?
|
245
265
|
set_relation(name, get_relation(name, metadata).substitute(object.substitutable))
|
266
|
+
elsif value = get_relation_for_set(name, metadata, object)
|
267
|
+
set_relation(name, value.substitute(object.substitutable))
|
246
268
|
else
|
247
269
|
__build__(name, object.substitutable, metadata)
|
248
270
|
end
|
@@ -190,12 +190,16 @@ module Mongoid
|
|
190
190
|
# @since 3.0.0
|
191
191
|
def bind_from_relational_parent(doc)
|
192
192
|
check_inverse!(doc)
|
193
|
-
bind_foreign_key(doc, base
|
193
|
+
bind_foreign_key(doc, record_id(base))
|
194
194
|
bind_polymorphic_type(doc, base.class.name)
|
195
195
|
bind_inverse(doc, base)
|
196
196
|
bind_inverse_of_field(doc, metadata.name)
|
197
197
|
end
|
198
198
|
|
199
|
+
def record_id(base)
|
200
|
+
base.__send__(metadata.primary_key)
|
201
|
+
end
|
202
|
+
|
199
203
|
# Ensure that the metadata on the base is correct, for the cases
|
200
204
|
# where we have multiple belongs to definitions and were are setting
|
201
205
|
# different parents in memory in order.
|
@@ -21,7 +21,7 @@ module Mongoid
|
|
21
21
|
def bind_one
|
22
22
|
binding do
|
23
23
|
check_inverses!(target)
|
24
|
-
bind_foreign_key(base, target
|
24
|
+
bind_foreign_key(base, record_id(target))
|
25
25
|
bind_polymorphic_inverse_type(base, target.class.name)
|
26
26
|
if inverse = metadata.inverse(target)
|
27
27
|
if set_base_metadata
|
@@ -20,7 +20,7 @@ module Mongoid
|
|
20
20
|
binding do
|
21
21
|
inverse_keys = doc.you_must(metadata.inverse_foreign_key)
|
22
22
|
if inverse_keys
|
23
|
-
inverse_keys.push(base
|
23
|
+
inverse_keys.push(record_id(base))
|
24
24
|
doc.reset_relation_criteria(metadata.inverse)
|
25
25
|
end
|
26
26
|
base.synced[metadata.foreign_key] = true
|
@@ -36,10 +36,10 @@ module Mongoid
|
|
36
36
|
# @since 2.0.0.rc.1
|
37
37
|
def unbind_one(doc)
|
38
38
|
binding do
|
39
|
-
base.send(metadata.foreign_key).delete_one(doc
|
39
|
+
base.send(metadata.foreign_key).delete_one(record_id(doc))
|
40
40
|
inverse_keys = doc.you_must(metadata.inverse_foreign_key)
|
41
41
|
if inverse_keys
|
42
|
-
inverse_keys.delete_one(base
|
42
|
+
inverse_keys.delete_one(record_id(base))
|
43
43
|
doc.reset_relation_criteria(metadata.inverse)
|
44
44
|
end
|
45
45
|
base.synced[metadata.foreign_key] = true
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid
|
3
|
+
module Relations
|
4
|
+
module CounterCache
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
# Reset the given counter using the .count() query from the
|
10
|
+
# db. This method is usuful in case that a counter got
|
11
|
+
# corrupted, or a new counter was added to the collection.
|
12
|
+
#
|
13
|
+
# @example Reset the given counter cache
|
14
|
+
# Post.reset_counters('50e0edd97c71c17ea9000001', :comments)
|
15
|
+
#
|
16
|
+
# @param [ String ] The id of the object that will be reset.
|
17
|
+
# @param [ Symbol, Array ] One or more counter caches to reset
|
18
|
+
#
|
19
|
+
# @since 3.1.0
|
20
|
+
def reset_counters(id, *counters)
|
21
|
+
object = find(id)
|
22
|
+
counters.each do |name|
|
23
|
+
meta = reflect_on_association(name)
|
24
|
+
inverse = meta.klass.reflect_on_association(meta.inverse)
|
25
|
+
counter_name = inverse.counter_cache_column_name
|
26
|
+
object.update_attribute(counter_name, object.send(name).count)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Update the given counters by the value factor. It uses the
|
31
|
+
# atomic $inc command.
|
32
|
+
#
|
33
|
+
# @example Add 5 to comments counter and remove 2 from likes
|
34
|
+
# counter.
|
35
|
+
# Post.update_counters('50e0edd97c71c17ea9000001',
|
36
|
+
# :comments_count => 5, :likes_count => -2)
|
37
|
+
#
|
38
|
+
# @param [ String ] The id of the object to update.
|
39
|
+
# @param [ Hash ] Key = counter_cahe and Value = factor.
|
40
|
+
#
|
41
|
+
# @since 3.1.0
|
42
|
+
def update_counters(id, counters)
|
43
|
+
counters.map do |key, value|
|
44
|
+
where(:_id => id).inc(key, value)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Increment the counter name from the entries that match the
|
49
|
+
# id by one. This method is used on associations callbacks
|
50
|
+
# when counter_cache is enable
|
51
|
+
#
|
52
|
+
# @example Increment comments counter
|
53
|
+
# Post.increment_counter(:comments_count, '50e0edd97c71c17ea9000001')
|
54
|
+
#
|
55
|
+
# @param [ Symbol ] Counter cache name
|
56
|
+
# @param [ String ] The id of the object that will be reset.
|
57
|
+
#
|
58
|
+
# @since 3.1.0
|
59
|
+
def increment_counter(counter_name, id)
|
60
|
+
update_counters(id, counter_name.to_sym => 1)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Decrement the counter name from the entries that match the
|
64
|
+
# id by one. This method is used on associations callbacks
|
65
|
+
# when counter_cache is enable
|
66
|
+
#
|
67
|
+
# @example Decrement comments counter
|
68
|
+
# Post.decrement_counter(:comments_count, '50e0edd97c71c17ea9000001')
|
69
|
+
#
|
70
|
+
# @param [ Symbol ] Counter cache name
|
71
|
+
# @param [ String ] The id of the object that will be reset.
|
72
|
+
#
|
73
|
+
# @since 3.1.0
|
74
|
+
def decrement_counter(counter_name, id)
|
75
|
+
update_counters(id, counter_name.to_sym => -1)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
# Add the callbacks responsible for update the counter cache field
|
81
|
+
#
|
82
|
+
# @api private
|
83
|
+
#
|
84
|
+
# @example Add the touchable.
|
85
|
+
# Person.add_counter_callbacks(meta)
|
86
|
+
#
|
87
|
+
# @param [ Metadata ] metadata The metadata for the relation.
|
88
|
+
#
|
89
|
+
# @since 3.1.0
|
90
|
+
def add_counter_cache_callbacks(meta)
|
91
|
+
name = meta.name
|
92
|
+
cache_column = meta.counter_cache_column_name.to_sym
|
93
|
+
|
94
|
+
after_create do
|
95
|
+
record = __send__(name)
|
96
|
+
record.class.increment_counter(cache_column, record.id) if record.try(:persisted?)
|
97
|
+
end
|
98
|
+
|
99
|
+
before_destroy do
|
100
|
+
record = __send__(name)
|
101
|
+
record.class.decrement_counter(cache_column, record.id) if record.try(:persisted?)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -6,6 +6,7 @@ module Mongoid
|
|
6
6
|
# Contains behaviour for executing operations in batch on embedded
|
7
7
|
# documents.
|
8
8
|
module Batchable
|
9
|
+
include Mongoid::Atomic::Positionable
|
9
10
|
|
10
11
|
# Insert new documents as a batch push ($pushAll). This ensures that
|
11
12
|
# all callbacks are run at the appropriate time and only 1 request is
|
@@ -36,7 +37,9 @@ module Mongoid
|
|
36
37
|
def batch_clear(docs)
|
37
38
|
pre_process_batch_remove(docs, :delete)
|
38
39
|
unless docs.empty?
|
39
|
-
collection.find(selector).update(
|
40
|
+
collection.find(selector).update(
|
41
|
+
positionally(selector, "$unset" => { path => true })
|
42
|
+
)
|
40
43
|
post_process_batch_remove(docs, :delete)
|
41
44
|
end
|
42
45
|
_unscoped.clear
|
@@ -53,8 +56,10 @@ module Mongoid
|
|
53
56
|
# @since 3.0.0
|
54
57
|
def batch_remove(docs, method = :delete)
|
55
58
|
removals = pre_process_batch_remove(docs, method)
|
56
|
-
if !docs.empty?
|
57
|
-
collection.find(selector).update(
|
59
|
+
if !docs.empty? && !_assigning?
|
60
|
+
collection.find(selector).update(
|
61
|
+
positionally(selector, "$pullAll" => { path => removals })
|
62
|
+
)
|
58
63
|
post_process_batch_remove(docs, method)
|
59
64
|
end
|
60
65
|
Threaded.clear_options!
|
@@ -126,7 +131,9 @@ module Mongoid
|
|
126
131
|
self.inserts_valid = true
|
127
132
|
inserts = pre_process_batch_insert(docs)
|
128
133
|
if insertable?
|
129
|
-
collection.find(selector).update(
|
134
|
+
collection.find(selector).update(
|
135
|
+
positionally(selector, operation => { path => inserts })
|
136
|
+
)
|
130
137
|
post_process_batch_insert(docs)
|
131
138
|
end
|
132
139
|
inserts
|
@@ -289,6 +296,7 @@ module Mongoid
|
|
289
296
|
def pre_process_batch_remove(docs, method)
|
290
297
|
docs.map do |doc|
|
291
298
|
self.path = doc.atomic_path unless path
|
299
|
+
execute_callback :before_remove, doc
|
292
300
|
if !_assigning? && !metadata.versioned?
|
293
301
|
doc.cascade!
|
294
302
|
doc.run_before_callbacks(:destroy) if method == :destroy
|
@@ -296,6 +304,7 @@ module Mongoid
|
|
296
304
|
target.delete_one(doc)
|
297
305
|
_unscoped.delete_one(doc)
|
298
306
|
unbind_one(doc)
|
307
|
+
execute_callback :after_remove, doc
|
299
308
|
doc.as_document
|
300
309
|
end
|
301
310
|
end
|
@@ -130,6 +130,7 @@ module Mongoid
|
|
130
130
|
#
|
131
131
|
# @since 2.0.0.rc.1
|
132
132
|
def delete(document)
|
133
|
+
execute_callback :before_remove, document
|
133
134
|
doc = target.delete_one(document)
|
134
135
|
if doc && !_binding?
|
135
136
|
_unscoped.delete_one(doc) unless doc.paranoid?
|
@@ -145,6 +146,7 @@ module Mongoid
|
|
145
146
|
end
|
146
147
|
end
|
147
148
|
reindex
|
149
|
+
execute_callback :after_remove, document
|
148
150
|
doc
|
149
151
|
end
|
150
152
|
|
@@ -175,6 +177,28 @@ module Mongoid
|
|
175
177
|
remove_all(conditions, :delete)
|
176
178
|
end
|
177
179
|
|
180
|
+
# Delete all the documents for which the provided block returns true.
|
181
|
+
#
|
182
|
+
# @example Delete the matching documents.
|
183
|
+
# person.addresses.delete_if do |doc|
|
184
|
+
# doc.state = "GA"
|
185
|
+
# end
|
186
|
+
#
|
187
|
+
# @return [ Many, Enumerator ] The relation or an enumerator if no
|
188
|
+
# block was provided.
|
189
|
+
#
|
190
|
+
# @since 3.1.0
|
191
|
+
def delete_if
|
192
|
+
if block_given?
|
193
|
+
target.each do |doc|
|
194
|
+
delete(doc) if yield(doc)
|
195
|
+
end
|
196
|
+
self
|
197
|
+
else
|
198
|
+
super
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
178
202
|
# Destroy all the documents in the association whilst running callbacks.
|
179
203
|
#
|
180
204
|
# @example Destroy all documents from the relation.
|
@@ -318,10 +342,12 @@ module Mongoid
|
|
318
342
|
#
|
319
343
|
# @since 2.0.0.rc.1
|
320
344
|
def append(document)
|
345
|
+
execute_callback :before_add, document
|
321
346
|
target.push(*scope([document]))
|
322
347
|
_unscoped.push(document)
|
323
348
|
integrate(document)
|
324
349
|
document._index = _unscoped.size - 1
|
350
|
+
execute_callback :after_add, document
|
325
351
|
end
|
326
352
|
|
327
353
|
# Instantiate the binding associated with this relation.
|
@@ -608,7 +634,10 @@ module Mongoid
|
|
608
634
|
#
|
609
635
|
# @since 2.1.0
|
610
636
|
def valid_options
|
611
|
-
[
|
637
|
+
[
|
638
|
+
:as, :cascade_callbacks, :cyclic, :order, :versioned, :store_as,
|
639
|
+
:before_add, :after_add, :before_remove, :after_remove
|
640
|
+
]
|
612
641
|
end
|
613
642
|
|
614
643
|
# Get the default validation setting for the relation. Determines if
|