mongoid 2.0.0.rc.7 → 2.0.0.rc.8
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/lib/config/locales/en.yml +3 -0
- data/lib/config/locales/id.yml +46 -0
- data/lib/config/locales/ja.yml +40 -0
- data/lib/config/locales/vi.yml +45 -0
- data/lib/mongoid.rb +5 -3
- data/lib/mongoid/attributes.rb +24 -63
- data/lib/mongoid/attributes/processing.rb +5 -2
- data/lib/mongoid/callbacks.rb +10 -0
- data/lib/mongoid/collection.rb +24 -0
- data/lib/mongoid/collections/master.rb +14 -6
- data/lib/mongoid/collections/operations.rb +1 -1
- data/lib/mongoid/collections/retry.rb +39 -0
- data/lib/mongoid/collections/slaves.rb +26 -10
- data/lib/mongoid/components.rb +4 -4
- data/lib/mongoid/config.rb +6 -3
- data/lib/mongoid/contexts.rb +0 -1
- data/lib/mongoid/contexts/enumerable.rb +19 -7
- data/lib/mongoid/contexts/mongo.rb +9 -5
- data/lib/mongoid/copyable.rb +10 -8
- data/lib/mongoid/criteria.rb +83 -61
- data/lib/mongoid/criterion/builder.rb +34 -0
- data/lib/mongoid/criterion/creational.rb +2 -2
- data/lib/mongoid/criterion/exclusion.rb +58 -32
- data/lib/mongoid/criterion/inclusion.rb +49 -10
- data/lib/mongoid/criterion/optional.rb +1 -1
- data/lib/mongoid/criterion/selector.rb +80 -11
- data/lib/mongoid/cursor.rb +6 -1
- data/lib/mongoid/default_scope.rb +27 -19
- data/lib/mongoid/document.rb +26 -1
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/mixed_relations.rb +37 -0
- data/lib/mongoid/extensions/object_id/conversions.rb +7 -4
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/field.rb +47 -30
- data/lib/mongoid/fields.rb +9 -2
- data/lib/mongoid/finders.rb +15 -49
- data/lib/mongoid/identity.rb +6 -4
- data/lib/mongoid/keys.rb +85 -31
- data/lib/mongoid/multi_parameter_attributes.rb +2 -2
- data/lib/mongoid/named_scope.rb +129 -28
- data/lib/mongoid/observer.rb +36 -0
- data/lib/mongoid/paranoia.rb +3 -3
- data/lib/mongoid/paths.rb +1 -1
- data/lib/mongoid/persistence.rb +2 -0
- data/lib/mongoid/persistence/atomic.rb +88 -0
- data/lib/mongoid/persistence/atomic/add_to_set.rb +30 -0
- data/lib/mongoid/persistence/atomic/inc.rb +28 -0
- data/lib/mongoid/persistence/atomic/operation.rb +44 -0
- data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
- data/lib/mongoid/persistence/atomic/push.rb +28 -0
- data/lib/mongoid/railtie.rb +13 -1
- data/lib/mongoid/relations.rb +1 -0
- data/lib/mongoid/relations/accessors.rb +20 -2
- data/lib/mongoid/relations/builders/embedded/one.rb +1 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +17 -6
- data/lib/mongoid/relations/builders/referenced/many.rb +2 -1
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -0
- data/lib/mongoid/relations/embedded/atomic.rb +86 -0
- data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
- data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
- data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
- data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
- data/lib/mongoid/relations/embedded/many.rb +57 -25
- data/lib/mongoid/relations/macros.rb +6 -4
- data/lib/mongoid/relations/many.rb +51 -10
- data/lib/mongoid/relations/metadata.rb +4 -2
- data/lib/mongoid/relations/proxy.rb +39 -24
- data/lib/mongoid/relations/referenced/many.rb +47 -26
- data/lib/mongoid/relations/referenced/many_to_many.rb +47 -14
- data/lib/mongoid/relations/referenced/one.rb +14 -0
- data/lib/mongoid/sharding.rb +51 -0
- data/lib/mongoid/state.rb +3 -2
- data/lib/mongoid/timestamps.rb +5 -29
- data/lib/mongoid/timestamps/created.rb +31 -0
- data/lib/mongoid/timestamps/updated.rb +33 -0
- data/lib/mongoid/validations.rb +10 -3
- data/lib/mongoid/validations/referenced.rb +58 -0
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/versioning.rb +67 -5
- data/lib/rails/generators/mongoid/model/templates/model.rb +2 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
- data/lib/rails/generators/mongoid_generator.rb +10 -1
- data/lib/rails/mongoid.rb +1 -0
- metadata +29 -8
- data/lib/mongoid/contexts/ids.rb +0 -25
- data/lib/mongoid/modifiers.rb +0 -24
- data/lib/mongoid/modifiers/command.rb +0 -18
- data/lib/mongoid/modifiers/inc.rb +0 -24
data/lib/mongoid/keys.rb
CHANGED
@@ -1,45 +1,83 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
|
+
|
4
|
+
# This module defines the behaviour for overriding the default ids on
|
5
|
+
# documents.
|
3
6
|
module Keys
|
4
7
|
extend ActiveSupport::Concern
|
5
|
-
included do
|
6
|
-
cattr_accessor :primary_key, :_identity
|
7
|
-
self._identity = { :type => BSON::ObjectId }
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
:using_object_ids?, :to => "self.class"
|
9
|
+
included do
|
10
|
+
cattr_accessor :primary_key, :object_ids
|
11
|
+
delegate :primary_key, :using_object_ids?, :to => "self.class"
|
13
12
|
end
|
14
13
|
|
15
|
-
|
14
|
+
private
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
16
|
+
# Determines if any field that the document id is composed of has changed.
|
17
|
+
#
|
18
|
+
# @example Has any key field changed?
|
19
|
+
# document.key_field_changed?
|
20
|
+
#
|
21
|
+
# @return [ true, false ] Has a key field changed?
|
22
|
+
#
|
23
|
+
# @since 2.0.0
|
24
|
+
def key_field_changed?
|
25
|
+
primary_key.any? { |field| changed.include?(field.to_s) }
|
26
|
+
end
|
27
|
+
|
28
|
+
# Sits around a save when composite keys are in play to handle the id magic
|
29
|
+
# if a key field has changed.
|
30
|
+
#
|
31
|
+
# @example Set the composite key.
|
32
|
+
# document.set_composite_key
|
33
|
+
#
|
34
|
+
# @param [ Proc ] block The block this surrounds.
|
35
|
+
#
|
36
|
+
# @since 2.0.0
|
37
|
+
def set_composite_key(&block)
|
38
|
+
if persisted? && key_field_changed?
|
39
|
+
swap_composite_keys(&block)
|
40
|
+
else
|
41
|
+
identify and block.call
|
28
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Swap out the composite key only after the document has been saved.
|
46
|
+
#
|
47
|
+
# @example Swap out the keys.
|
48
|
+
# document.swap_composite_keys
|
49
|
+
#
|
50
|
+
# @param [ Proc ] block The save block getting called.
|
51
|
+
#
|
52
|
+
# @since 2.0.0
|
53
|
+
def swap_composite_keys(&block)
|
54
|
+
old_id, new_id = id.dup, identify
|
55
|
+
@attributes["_id"] = old_id
|
56
|
+
block.call
|
57
|
+
@attributes["_id"] = new_id
|
58
|
+
end
|
59
|
+
|
60
|
+
module ClassMethods #:nodoc:
|
29
61
|
|
30
62
|
# Used for telling Mongoid on a per model basis whether to override the
|
31
63
|
# default +BSON::ObjectId+ and use a different type. This will be
|
32
64
|
# expanded in the future for requiring a PkFactory if the type is not a
|
33
65
|
# +BSON::ObjectId+ or +String+.
|
34
66
|
#
|
35
|
-
#
|
36
|
-
#
|
67
|
+
# @example Change the documents key type.
|
37
68
|
# class Person
|
38
69
|
# include Mongoid::Document
|
39
70
|
# identity :type => String
|
40
71
|
# end
|
72
|
+
#
|
73
|
+
# @param [ Hash ] options The options.
|
74
|
+
#
|
75
|
+
# @option options [ Class ] :type The type of the id.
|
76
|
+
#
|
77
|
+
# @since 2.0.0.beta.1
|
41
78
|
def identity(options = {})
|
42
|
-
|
79
|
+
fields["_id"].type = options[:type]
|
80
|
+
@object_ids = id_is_object
|
43
81
|
end
|
44
82
|
|
45
83
|
# Defines the field that will be used for the id of this +Document+. This
|
@@ -47,30 +85,46 @@ module Mongoid #:nodoc:
|
|
47
85
|
# the field that was supplied. This is good for use for readable URLS in
|
48
86
|
# web applications.
|
49
87
|
#
|
50
|
-
#
|
51
|
-
#
|
88
|
+
# @example Create a composite id.
|
52
89
|
# class Person
|
53
90
|
# include Mongoid::Document
|
54
91
|
# key :first_name, :last_name
|
55
92
|
# end
|
93
|
+
#
|
94
|
+
# @param [ Array<Symbol> ] The fields the key is composed of.
|
95
|
+
#
|
96
|
+
# @since 1.0.0
|
56
97
|
def key(*fields)
|
57
98
|
self.primary_key = fields
|
58
99
|
identity(:type => String)
|
59
|
-
set_callback
|
100
|
+
set_callback(:save, :around, :set_composite_key)
|
60
101
|
end
|
61
102
|
|
62
103
|
# Convenience method for determining if we are using +BSON::ObjectIds+ as
|
63
104
|
# our id.
|
64
105
|
#
|
65
|
-
#
|
106
|
+
# @example Does this class use object ids?
|
107
|
+
# person.using_object_ids?
|
66
108
|
#
|
67
|
-
#
|
109
|
+
# @return [ true, false ] If the class uses BSON::ObjectIds for the id.
|
68
110
|
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
# true if we are using BSON::ObjectIds
|
111
|
+
# @since 1.0.0
|
72
112
|
def using_object_ids?
|
73
|
-
|
113
|
+
@object_ids ||= id_is_object
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
# Is the id field type an object id?
|
119
|
+
#
|
120
|
+
# @example Is type an object id.
|
121
|
+
# Class.id_is_object
|
122
|
+
#
|
123
|
+
# @return [ true, false ] Is the id an object id.
|
124
|
+
#
|
125
|
+
# @since 2.0.0
|
126
|
+
def id_is_object
|
127
|
+
fields["_id"].type == BSON::ObjectId
|
74
128
|
end
|
75
129
|
end
|
76
130
|
end
|
@@ -27,7 +27,7 @@ module Mongoid #:nodoc:
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
def process(attrs = nil)
|
30
|
+
def process(attrs = nil, guard_protected_attributes = true)
|
31
31
|
if attrs
|
32
32
|
errors = []
|
33
33
|
attributes = {}
|
@@ -56,7 +56,7 @@ module Mongoid #:nodoc:
|
|
56
56
|
raise Errors::MultiparameterAssignmentErrors.new(errors), "#{errors.size} error(s) on assignment of multiparameter attributes"
|
57
57
|
end
|
58
58
|
|
59
|
-
super attributes
|
59
|
+
super attributes, guard_protected_attributes
|
60
60
|
else
|
61
61
|
super
|
62
62
|
end
|
data/lib/mongoid/named_scope.rb
CHANGED
@@ -1,36 +1,137 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Mongoid #:nodoc:
|
3
|
+
|
4
|
+
# This module contains the named scoping behaviour.
|
3
5
|
module NamedScope
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
#
|
10
|
-
# class Person
|
11
|
-
# include Mongoid::Document
|
12
|
-
# field :active, :type => Boolean
|
13
|
-
# field :count, :type => Integer
|
14
|
-
#
|
15
|
-
# named_scope :active, :where => { :active => true }
|
16
|
-
# named_scope :count_gt_one, :where => { :count.gt => 1 }
|
17
|
-
# named_scope :at_least_count, lambda { |count| { :where => { :count.gt => count } } }
|
18
|
-
# end
|
19
|
-
def named_scope(name, conditions = {}, &block)
|
20
|
-
name = name.to_sym
|
21
|
-
scopes[name] = Scope.new(conditions, &block)
|
22
|
-
(class << self; self; end).class_eval <<-EOT
|
23
|
-
def #{name}(*args)
|
24
|
-
scope = scopes[:#{name}]
|
25
|
-
scope.extend(criteria.fuse(scope.conditions.scoped(*args)))
|
26
|
-
end
|
27
|
-
EOT
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class_attribute :scopes
|
10
|
+
self.scopes = {}
|
28
11
|
end
|
29
|
-
alias :scope :named_scope
|
30
12
|
|
31
|
-
|
32
|
-
|
33
|
-
|
13
|
+
module ClassMethods #:nodoc:
|
14
|
+
|
15
|
+
# Gets either the last scope on the stack or creates a new criteria.
|
16
|
+
#
|
17
|
+
# @example Get the last or new.
|
18
|
+
# Person.scoping(true)
|
19
|
+
#
|
20
|
+
# @param [ true, false ] embedded Is this scope for an embedded doc?
|
21
|
+
# @param [ true, false ] scoped Are we applying default scoping?
|
22
|
+
#
|
23
|
+
# @return [ Criteria ] The last scope or a new one.
|
24
|
+
#
|
25
|
+
# @since 2.0.0
|
26
|
+
def criteria(embedded = false, scoped = true)
|
27
|
+
scope_stack.last || Criteria.new(self, embedded).tap do |crit|
|
28
|
+
return crit.fuse(default_scoping) if default_scoping && scoped
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Creates a named_scope for the +Document+, similar to ActiveRecord's
|
33
|
+
# named_scopes. +NamedScopes+ are proxied +Criteria+ objects that can be
|
34
|
+
# chained.
|
35
|
+
#
|
36
|
+
# @example Create named scopes.
|
37
|
+
#
|
38
|
+
# class Person
|
39
|
+
# include Mongoid::Document
|
40
|
+
# field :active, :type => Boolean
|
41
|
+
# field :count, :type => Integer
|
42
|
+
#
|
43
|
+
# scope :active, :where => { :active => true }
|
44
|
+
# scope :count_gt_one, :where => { :count.gt => 1 }
|
45
|
+
# scope :at_least_count, lambda { |count| { :where => { :count.gt => count } } }
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# @param [ Symbol ] name The name of the scope.
|
49
|
+
# @param [ Hash, Criteria ] conditions The conditions of the scope.
|
50
|
+
#
|
51
|
+
# @since 1.0.0
|
52
|
+
def scope(name, conditions = {}, &block)
|
53
|
+
name = name.to_sym
|
54
|
+
valid_scope_name?(name)
|
55
|
+
scopes[name] = Scope.new(conditions, &block)
|
56
|
+
(class << self; self; end).class_eval <<-EOT
|
57
|
+
def #{name}(*args)
|
58
|
+
scope = scopes[:#{name}]
|
59
|
+
scope.extend(criteria.fuse(scope.conditions.scoped(*args)))
|
60
|
+
end
|
61
|
+
EOT
|
62
|
+
end
|
63
|
+
alias :named_scope :scope
|
64
|
+
|
65
|
+
# Get a criteria object for the class, scoped to the default if defined.
|
66
|
+
#
|
67
|
+
# @example Get a scoped criteria.
|
68
|
+
# Person.scoped
|
69
|
+
#
|
70
|
+
# @param [ true, false ] embedded Is the criteria for embedded docs?
|
71
|
+
#
|
72
|
+
# @return [ Criteria ] The scoped criteria.
|
73
|
+
#
|
74
|
+
# @since 2.0.0
|
75
|
+
def scoped(embedded = false)
|
76
|
+
criteria(embedded, true)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Initializes and returns the current scope stack.
|
80
|
+
#
|
81
|
+
# @example Get the scope stack.
|
82
|
+
# Person.scope_stack
|
83
|
+
#
|
84
|
+
# @return [ Array<Criteria> ] The scope stack.
|
85
|
+
#
|
86
|
+
# @since 1.0.0
|
87
|
+
def scope_stack
|
88
|
+
scope_stack_for = Thread.current[:mongoid_scope_stack] ||= {}
|
89
|
+
scope_stack_for[object_id] ||= []
|
90
|
+
end
|
91
|
+
|
92
|
+
# Get a criteria object for the class, ignoring default scoping.
|
93
|
+
#
|
94
|
+
# @example Get an unscoped criteria.
|
95
|
+
# Person.scoped
|
96
|
+
#
|
97
|
+
# @param [ true, false ] embedded Is the criteria for embedded docs?
|
98
|
+
#
|
99
|
+
# @return [ Criteria ] The unscoped criteria.
|
100
|
+
#
|
101
|
+
# @since 2.0.0
|
102
|
+
def unscoped(embedded = false)
|
103
|
+
criteria(embedded, false)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Pushes the provided criteria onto the scope stack, and removes it after the
|
107
|
+
# provided block is yielded.
|
108
|
+
#
|
109
|
+
# @example Yield to the criteria.
|
110
|
+
# Person.with_scope(criteria)
|
111
|
+
#
|
112
|
+
# @param [ Criteria ] criteria The criteria to apply.
|
113
|
+
#
|
114
|
+
# @return [ Criteria ] The yielded criteria.
|
115
|
+
#
|
116
|
+
# @since 1.0.0
|
117
|
+
def with_scope(criteria)
|
118
|
+
scope_stack = self.scope_stack
|
119
|
+
scope_stack << criteria
|
120
|
+
begin
|
121
|
+
yield criteria
|
122
|
+
ensure
|
123
|
+
scope_stack.pop
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
protected
|
128
|
+
|
129
|
+
def valid_scope_name?(name)
|
130
|
+
if !scopes[name] && respond_to?(name, true)
|
131
|
+
Mongoid.logger.warn "Creating scope :#{name}. " \
|
132
|
+
"Overwriting existing method #{self.name}.#{name}."
|
133
|
+
end
|
134
|
+
end
|
34
135
|
end
|
35
136
|
end
|
36
137
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Mongoid #:nodoc:
|
3
|
+
class Observer < ActiveModel::Observer
|
4
|
+
def initialize
|
5
|
+
super
|
6
|
+
observed_descendants.each { |klass| add_observer!(klass) }
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def observed_descendants
|
12
|
+
observed_classes.sum([]) { |klass| klass.descendants }
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_observer!(klass)
|
16
|
+
super
|
17
|
+
define_callbacks klass
|
18
|
+
end
|
19
|
+
|
20
|
+
def define_callbacks(klass)
|
21
|
+
observer = self
|
22
|
+
observer_name = observer.class.name.underscore.gsub('/', '__')
|
23
|
+
|
24
|
+
Mongoid::Callbacks::CALLBACKS.each do |callback|
|
25
|
+
next unless respond_to?(callback)
|
26
|
+
callback_meth = :"_notify_#{observer_name}_for_#{callback}"
|
27
|
+
unless klass.respond_to?(callback_meth)
|
28
|
+
klass.send(:define_method, callback_meth) do |&block|
|
29
|
+
observer.send(callback, self, &block)
|
30
|
+
end
|
31
|
+
klass.send(callback, callback_meth)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
data/lib/mongoid/paranoia.rb
CHANGED
@@ -42,19 +42,19 @@ module Mongoid #:nodoc:
|
|
42
42
|
#
|
43
43
|
# Example:
|
44
44
|
#
|
45
|
-
# <tt>document.
|
45
|
+
# <tt>document.remove</tt>
|
46
46
|
#
|
47
47
|
# Returns:
|
48
48
|
#
|
49
49
|
# true
|
50
|
-
def
|
50
|
+
def remove(options = {})
|
51
51
|
now = Time.now
|
52
52
|
collection.update({ :_id => self.id }, { '$set' => { :deleted_at => Time.now } })
|
53
53
|
@attributes["deleted_at"] = now
|
54
54
|
true
|
55
55
|
end
|
56
56
|
|
57
|
-
alias :delete :
|
57
|
+
alias :delete :remove
|
58
58
|
|
59
59
|
# Determines if this document is destroyed.
|
60
60
|
#
|
data/lib/mongoid/paths.rb
CHANGED
@@ -55,7 +55,7 @@ module Mongoid #:nodoc:
|
|
55
55
|
#
|
56
56
|
# <tt>address.selector</tt>
|
57
57
|
def _selector
|
58
|
-
embedded? ? _parent._selector.merge("#{_path}._id" => id) : { "_id" => id }
|
58
|
+
(embedded? ? _parent._selector.merge("#{_path}._id" => id) : { "_id" => id }).merge(shard_key_selector)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
end
|
data/lib/mongoid/persistence.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "mongoid/persistence/atomic"
|
2
3
|
require "mongoid/persistence/command"
|
3
4
|
require "mongoid/persistence/insert"
|
4
5
|
require "mongoid/persistence/insert_embedded"
|
@@ -19,6 +20,7 @@ module Mongoid #:nodoc:
|
|
19
20
|
# document.upsert
|
20
21
|
module Persistence
|
21
22
|
extend ActiveSupport::Concern
|
23
|
+
include Atomic
|
22
24
|
|
23
25
|
# Remove the document from the datbase with callbacks.
|
24
26
|
#
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "mongoid/persistence/atomic/operation"
|
3
|
+
require "mongoid/persistence/atomic/add_to_set"
|
4
|
+
require "mongoid/persistence/atomic/inc"
|
5
|
+
require "mongoid/persistence/atomic/pull_all"
|
6
|
+
require "mongoid/persistence/atomic/push"
|
7
|
+
|
8
|
+
module Mongoid #:nodoc:
|
9
|
+
module Persistence #:nodoc:
|
10
|
+
|
11
|
+
# This module provides the explicit atomic operations helpers on the
|
12
|
+
# document itself.
|
13
|
+
module Atomic
|
14
|
+
|
15
|
+
# Performs an atomic $addToSet of the provided value on the supplied field.
|
16
|
+
# If the field does not exist it will be initialized as an empty array.
|
17
|
+
#
|
18
|
+
# If the value already exists on the array it will not be added.
|
19
|
+
#
|
20
|
+
# @example Add only a unique value on the field.
|
21
|
+
# person.add_to_set(:aliases, "Bond")
|
22
|
+
#
|
23
|
+
# @param [ Symbol ] field The name of the field.
|
24
|
+
# @param [ Object ] value The value to add.
|
25
|
+
# @param [ Hash ] options The mongo persistence options.
|
26
|
+
#
|
27
|
+
# @return [ Array<Object> ] The new value of the field.
|
28
|
+
#
|
29
|
+
# @since 2.0.0
|
30
|
+
def add_to_set(field, value, options = {})
|
31
|
+
AddToSet.new(self, field, value, options).persist
|
32
|
+
end
|
33
|
+
|
34
|
+
# Performs an atomic $inc of the provided value on the supplied
|
35
|
+
# field. If the field does not exist it will be initialized as
|
36
|
+
# the provided value.
|
37
|
+
#
|
38
|
+
# @example Increment a field.
|
39
|
+
# person.inc(:score, 2)
|
40
|
+
#
|
41
|
+
# @param [ Symbol ] field The name of the field.
|
42
|
+
# @param [ Integer ] value The value to increment.
|
43
|
+
# @param [ Hash ] options The mongo persistence options.
|
44
|
+
#
|
45
|
+
# @return [ Array<Object> ] The new value of the field.
|
46
|
+
#
|
47
|
+
# @since 2.0.0
|
48
|
+
def inc(field, value, options = {})
|
49
|
+
Inc.new(self, field, value, options).persist
|
50
|
+
end
|
51
|
+
|
52
|
+
# Performs an atomic $pullAll of the provided value on the supplied
|
53
|
+
# field. If the field does not exist it will be initialized as an
|
54
|
+
# empty array.
|
55
|
+
#
|
56
|
+
# @example Pull the values from the field.
|
57
|
+
# person.pull_all(:aliases, [ "Bond", "James" ])
|
58
|
+
#
|
59
|
+
# @param [ Symbol ] field The name of the field.
|
60
|
+
# @param [ Array<Object> ] value The values to pull.
|
61
|
+
# @param [ Hash ] options The mongo persistence options.
|
62
|
+
#
|
63
|
+
# @return [ Array<Object> ] The new value of the field.
|
64
|
+
#
|
65
|
+
# @since 2.0.0
|
66
|
+
def pull_all(field, value, options = {})
|
67
|
+
PullAll.new(self, field, value, options).persist
|
68
|
+
end
|
69
|
+
|
70
|
+
# Performs an atomic $push of the provided value on the supplied field. If
|
71
|
+
# the field does not exist it will be initialized as an empty array.
|
72
|
+
#
|
73
|
+
# @example Push a value on the field.
|
74
|
+
# person.push(:aliases, "Bond")
|
75
|
+
#
|
76
|
+
# @param [ Symbol ] field The name of the field.
|
77
|
+
# @param [ Object ] value The value to push.
|
78
|
+
# @param [ Hash ] options The mongo persistence options.
|
79
|
+
#
|
80
|
+
# @return [ Array<Object> ] The new value of the field.
|
81
|
+
#
|
82
|
+
# @since 2.0.0
|
83
|
+
def push(field, value, options = {})
|
84
|
+
Push.new(self, field, value, options).persist
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|