mongo_mapper 0.13.0 → 0.15.1
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.
- checksums.yaml +5 -5
- data/LICENSE +1 -1
- data/README.md +61 -0
- data/examples/keys.rb +1 -1
- data/examples/modifiers/set.rb +1 -1
- data/examples/querying.rb +1 -1
- data/examples/safe.rb +2 -2
- data/examples/scopes.rb +1 -1
- data/lib/mongo_mapper.rb +7 -0
- data/lib/mongo_mapper/connection.rb +16 -37
- data/lib/mongo_mapper/document.rb +4 -0
- data/lib/mongo_mapper/extensions/array.rb +14 -6
- data/lib/mongo_mapper/extensions/hash.rb +15 -3
- data/lib/mongo_mapper/extensions/object.rb +4 -0
- data/lib/mongo_mapper/extensions/object_id.rb +5 -1
- data/lib/mongo_mapper/extensions/string.rb +13 -5
- data/lib/mongo_mapper/extensions/symbol.rb +18 -0
- data/lib/mongo_mapper/plugins/accessible.rb +15 -5
- data/lib/mongo_mapper/plugins/associations.rb +7 -6
- data/lib/mongo_mapper/plugins/associations/base.rb +27 -14
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +10 -1
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +9 -8
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +12 -11
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +4 -4
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +60 -29
- data/lib/mongo_mapper/plugins/associations/in_foreign_array_proxy.rb +136 -0
- data/lib/mongo_mapper/plugins/associations/many_association.rb +4 -2
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +18 -16
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +55 -48
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +14 -13
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +7 -6
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +7 -5
- data/lib/mongo_mapper/plugins/associations/one_as_proxy.rb +14 -11
- data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +14 -13
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +9 -9
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +27 -26
- data/lib/mongo_mapper/plugins/associations/proxy.rb +36 -29
- data/lib/mongo_mapper/plugins/associations/single_association.rb +5 -4
- data/lib/mongo_mapper/plugins/callbacks.rb +13 -0
- data/lib/mongo_mapper/plugins/counter_cache.rb +97 -0
- data/lib/mongo_mapper/plugins/dirty.rb +29 -37
- data/lib/mongo_mapper/plugins/document.rb +1 -1
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +10 -9
- data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +18 -17
- data/lib/mongo_mapper/plugins/embedded_callbacks.rb +2 -1
- data/lib/mongo_mapper/plugins/embedded_document.rb +1 -1
- data/lib/mongo_mapper/plugins/identity_map.rb +4 -2
- data/lib/mongo_mapper/plugins/indexes.rb +14 -7
- data/lib/mongo_mapper/plugins/keys.rb +170 -151
- data/lib/mongo_mapper/plugins/keys/key.rb +27 -16
- data/lib/mongo_mapper/plugins/keys/static.rb +45 -0
- data/lib/mongo_mapper/plugins/modifiers.rb +64 -38
- data/lib/mongo_mapper/plugins/partial_updates.rb +86 -0
- data/lib/mongo_mapper/plugins/persistence.rb +13 -8
- data/lib/mongo_mapper/plugins/protected.rb +6 -5
- data/lib/mongo_mapper/plugins/querying.rb +85 -42
- data/lib/mongo_mapper/plugins/querying/decorated_plucky_query.rb +20 -15
- data/lib/mongo_mapper/plugins/rails.rb +1 -0
- data/lib/mongo_mapper/plugins/safe.rb +10 -4
- data/lib/mongo_mapper/plugins/sci.rb +0 -0
- data/lib/mongo_mapper/plugins/scopes.rb +78 -7
- data/lib/mongo_mapper/plugins/stats.rb +17 -0
- data/lib/mongo_mapper/plugins/strong_parameters.rb +26 -0
- data/lib/mongo_mapper/plugins/timestamps.rb +1 -0
- data/lib/mongo_mapper/plugins/validations.rb +1 -1
- data/lib/mongo_mapper/railtie.rb +4 -3
- data/lib/mongo_mapper/utils.rb +2 -2
- data/lib/mongo_mapper/version.rb +1 -1
- data/lib/rails/generators/mongo_mapper/config/config_generator.rb +12 -13
- data/lib/rails/generators/mongo_mapper/model/model_generator.rb +9 -9
- data/spec/examples.txt +1717 -0
- data/spec/functional/accessible_spec.rb +19 -13
- data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +13 -13
- data/spec/functional/associations/belongs_to_proxy_spec.rb +36 -20
- data/spec/functional/associations/in_array_proxy_spec.rb +145 -10
- data/spec/functional/associations/in_foreign_array_proxy_spec.rb +321 -0
- data/spec/functional/associations/many_documents_as_proxy_spec.rb +6 -6
- data/spec/functional/associations/many_documents_proxy_spec.rb +85 -14
- data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +13 -13
- data/spec/functional/associations/many_embedded_proxy_spec.rb +1 -1
- data/spec/functional/associations/many_polymorphic_proxy_spec.rb +4 -4
- data/spec/functional/associations/one_as_proxy_spec.rb +10 -10
- data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +9 -9
- data/spec/functional/associations/one_embedded_proxy_spec.rb +3 -3
- data/spec/functional/associations/one_proxy_spec.rb +10 -10
- data/spec/functional/associations_spec.rb +3 -3
- data/spec/functional/binary_spec.rb +2 -2
- data/spec/functional/caching_spec.rb +8 -15
- data/spec/functional/callbacks_spec.rb +89 -2
- data/spec/functional/counter_cache_spec.rb +235 -0
- data/spec/functional/dirty_spec.rb +63 -46
- data/spec/functional/document_spec.rb +30 -5
- data/spec/functional/dumpable_spec.rb +1 -1
- data/spec/functional/embedded_document_spec.rb +17 -17
- data/spec/functional/identity_map_spec.rb +29 -16
- data/spec/functional/indexes_spec.rb +19 -18
- data/spec/functional/keys_spec.rb +86 -28
- data/spec/functional/logger_spec.rb +3 -3
- data/spec/functional/modifiers_spec.rb +81 -19
- data/spec/functional/partial_updates_spec.rb +577 -0
- data/spec/functional/protected_spec.rb +14 -14
- data/spec/functional/querying_spec.rb +77 -28
- data/spec/functional/safe_spec.rb +23 -27
- data/spec/functional/sci_spec.rb +9 -9
- data/spec/functional/scopes_spec.rb +235 -2
- data/spec/functional/static_keys_spec.rb +153 -0
- data/spec/functional/stats_spec.rb +86 -0
- data/spec/functional/strong_parameters_spec.rb +49 -0
- data/spec/functional/touch_spec.rb +1 -1
- data/spec/functional/validations_spec.rb +51 -57
- data/spec/quality_spec.rb +51 -0
- data/spec/spec_helper.rb +37 -9
- data/spec/support/matchers.rb +5 -14
- data/spec/unit/associations/base_spec.rb +12 -12
- data/spec/unit/associations/belongs_to_association_spec.rb +2 -2
- data/spec/unit/associations/many_association_spec.rb +2 -2
- data/spec/unit/associations/one_association_spec.rb +2 -2
- data/spec/unit/associations/proxy_spec.rb +19 -20
- data/spec/unit/clone_spec.rb +1 -1
- data/spec/unit/document_spec.rb +8 -8
- data/spec/unit/dynamic_finder_spec.rb +8 -8
- data/spec/unit/embedded_document_spec.rb +18 -19
- data/spec/unit/extensions_spec.rb +41 -17
- data/spec/unit/identity_map_middleware_spec.rb +65 -96
- data/spec/unit/key_spec.rb +28 -26
- data/spec/unit/keys_spec.rb +20 -11
- data/spec/unit/model_generator_spec.rb +0 -0
- data/spec/unit/mongo_mapper_spec.rb +38 -85
- data/spec/unit/rails_spec.rb +5 -0
- data/spec/unit/serialization_spec.rb +1 -1
- data/spec/unit/time_zones_spec.rb +2 -2
- data/spec/unit/validations_spec.rb +46 -33
- metadata +66 -37
- data/README.rdoc +0 -59
- data/lib/mongo_mapper/connections/10gen.rb +0 -0
- data/lib/mongo_mapper/connections/moped.rb +0 -0
- data/lib/mongo_mapper/extensions/ordered_hash.rb +0 -23
@@ -3,10 +3,11 @@ module MongoMapper
|
|
3
3
|
module Plugins
|
4
4
|
module Keys
|
5
5
|
class Key
|
6
|
-
|
7
|
-
|
6
|
+
RESERVED_KEYS = %w( id class object_id attributes )
|
8
7
|
ID_STR = '_id'
|
9
8
|
|
9
|
+
attr_accessor :name, :type, :options, :default, :ivar, :abbr, :accessors
|
10
|
+
|
10
11
|
def initialize(*args)
|
11
12
|
options_from_args = args.extract_options!
|
12
13
|
@name, @type = args.shift.to_s, args.shift
|
@@ -60,12 +61,17 @@ module MongoMapper
|
|
60
61
|
# Special Case: Generate default _id on access
|
61
62
|
value = default_value if @is_id and !value
|
62
63
|
|
64
|
+
value = type.from_mongo(value)
|
65
|
+
|
63
66
|
if @typecast
|
64
|
-
klass = typecast_class
|
65
|
-
|
66
|
-
|
67
|
-
type
|
67
|
+
klass = typecast_class # Don't make this lookup on every call
|
68
|
+
# typecast assumes array-ish object.
|
69
|
+
value = value.map { |v| klass.from_mongo(v) }
|
70
|
+
# recast it in the original type
|
71
|
+
value = type.from_mongo(value)
|
68
72
|
end
|
73
|
+
|
74
|
+
value
|
69
75
|
end
|
70
76
|
|
71
77
|
def set(value)
|
@@ -93,6 +99,10 @@ module MongoMapper
|
|
93
99
|
!!@name.match(/\A[a-z_][a-z0-9_]*\z/i)
|
94
100
|
end
|
95
101
|
|
102
|
+
def reserved_name?
|
103
|
+
RESERVED_KEYS.include?(@name)
|
104
|
+
end
|
105
|
+
|
96
106
|
def read_accessor?
|
97
107
|
any_accessor? ["read"]
|
98
108
|
end
|
@@ -111,18 +121,19 @@ module MongoMapper
|
|
111
121
|
return !(@accessors & arr_opt).empty?
|
112
122
|
end
|
113
123
|
|
114
|
-
|
115
|
-
def typecast_class
|
116
|
-
@typecast_class ||= options[:typecast].constantize
|
117
|
-
end
|
124
|
+
private
|
118
125
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
126
|
+
def typecast_class
|
127
|
+
@typecast_class ||= options[:typecast].constantize
|
128
|
+
end
|
129
|
+
|
130
|
+
def validate_key_name!
|
131
|
+
if reserved_name?
|
132
|
+
raise MongoMapper::InvalidKey.new("`#{@name}` is a reserved key name")
|
133
|
+
elsif !valid_ruby_name?
|
134
|
+
raise MongoMapper::InvalidKey.new("`#{@name}` is not a valid key name. Keys must match [a-z][a-z0-9_]*")
|
125
135
|
end
|
136
|
+
end
|
126
137
|
end
|
127
138
|
end
|
128
139
|
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module Keys
|
4
|
+
module Static
|
5
|
+
class MissingKeyError < StandardError; end
|
6
|
+
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
attr_writer :static_keys
|
11
|
+
|
12
|
+
def static_keys
|
13
|
+
@static_keys || false
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def read_key(name)
|
18
|
+
if !self.class.static_keys || self.class.key?(name)
|
19
|
+
super
|
20
|
+
else
|
21
|
+
raise MissingKeyError, "Tried to read the key #{name.inspect}, but no key was defined. Either define key :#{name} or set self.static_keys = false"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def write_key(name, value)
|
28
|
+
if !self.class.static_keys || self.class.key?(name)
|
29
|
+
super
|
30
|
+
else
|
31
|
+
raise MissingKeyError, "Tried to write the key #{name.inspect}, but no key was defined. Either define key :#{name} or set self.static_keys = false"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def load_from_database(attrs, with_cast = false)
|
36
|
+
return super if !self.class.static_keys || !attrs.respond_to?(:each)
|
37
|
+
|
38
|
+
attrs = attrs.select { |key, _| self.class.key?(key) }
|
39
|
+
|
40
|
+
super(attrs, with_cast)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -13,7 +13,7 @@ module MongoMapper
|
|
13
13
|
criteria, keys, options = criteria_and_keys_from_args(args)
|
14
14
|
values, to_decrement = keys.values, {}
|
15
15
|
keys.keys.each_with_index { |k, i| to_decrement[k] = -values[i].abs }
|
16
|
-
collection.
|
16
|
+
collection.update_many(criteria, {'$inc' => to_decrement}, options || {})
|
17
17
|
end
|
18
18
|
|
19
19
|
def set(*args)
|
@@ -44,7 +44,16 @@ module MongoMapper
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def push_all(*args)
|
47
|
-
|
47
|
+
Kernel.warn "push_all no longer supported. use $push with $each"
|
48
|
+
|
49
|
+
hash = args.pop
|
50
|
+
ids = args
|
51
|
+
|
52
|
+
push_values = hash.inject({}) do |hsh, (key, values)|
|
53
|
+
{ key => { '$each' => values } }
|
54
|
+
end
|
55
|
+
|
56
|
+
modifier_update('$addToSet', [ids, push_values].flatten)
|
48
57
|
end
|
49
58
|
|
50
59
|
def add_to_set(*args)
|
@@ -64,61 +73,64 @@ module MongoMapper
|
|
64
73
|
modifier_update('$pop', args)
|
65
74
|
end
|
66
75
|
|
67
|
-
def
|
68
|
-
args
|
69
|
-
args[:
|
70
|
-
|
76
|
+
def find_one_and_update(args)
|
77
|
+
args = args.dup
|
78
|
+
args[:query] = dealias_keys(args.delete :query) if args.key? :query
|
79
|
+
args[:update] = dealias_keys(args.delete :update) if args.key? :update
|
80
|
+
collection.find_one_and_update(args[:query], args[:update], args)
|
71
81
|
end
|
82
|
+
alias_method :find_and_modify, :find_one_and_update
|
72
83
|
|
73
84
|
def upsert(selector, updates, args = {})
|
74
85
|
criteria = dealias_keys(selector)
|
75
86
|
updates = dealias_keys(updates)
|
76
|
-
collection.
|
87
|
+
collection.update_one(criteria, updates, args.merge(upsert: true))
|
77
88
|
end
|
78
89
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
90
|
+
private
|
91
|
+
|
92
|
+
def modifier_update(modifier, args)
|
93
|
+
criteria, updates, options = criteria_and_keys_from_args(args)
|
94
|
+
if options
|
95
|
+
collection.update_many(criteria, {modifier => updates}, options)
|
96
|
+
else
|
97
|
+
collection.update_many(criteria, {modifier => updates})
|
87
98
|
end
|
99
|
+
end
|
88
100
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
end
|
98
|
-
upgrade_legacy_safe_usage!(options)
|
99
|
-
updates = dealias_keys updates
|
100
|
-
|
101
|
-
[criteria_hash(criteria).to_hash, updates, options]
|
101
|
+
def criteria_and_keys_from_args(args)
|
102
|
+
if args[0].is_a?(Hash)
|
103
|
+
criteria = args[0]
|
104
|
+
updates = args[1]
|
105
|
+
options = args[2]
|
106
|
+
else
|
107
|
+
criteria, (updates, options) = args.partition { |a| !a.is_a?(Hash) }
|
108
|
+
criteria = { :id => criteria }
|
102
109
|
end
|
110
|
+
upgrade_legacy_safe_usage!(options)
|
111
|
+
updates = dealias_keys updates
|
103
112
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
113
|
+
[criteria_hash(criteria).to_hash, updates, options]
|
114
|
+
end
|
115
|
+
|
116
|
+
def upgrade_legacy_safe_usage!(options)
|
117
|
+
if options and options.key?(:safe)
|
118
|
+
options.merge! Utils.get_safe_options(options)
|
119
|
+
options.delete :safe
|
109
120
|
end
|
121
|
+
end
|
110
122
|
end
|
111
123
|
|
112
124
|
def unset(*args)
|
113
125
|
self.class.unset({:_id => id}, *args)
|
114
126
|
end
|
115
127
|
|
116
|
-
def increment(
|
117
|
-
self.class.increment({:_id => id},
|
128
|
+
def increment(args, options=nil)
|
129
|
+
self.class.increment({:_id => id}, _args_for_counter(args), options)
|
118
130
|
end
|
119
131
|
|
120
|
-
def decrement(
|
121
|
-
self.class.decrement({:_id => id},
|
132
|
+
def decrement(args, options=nil)
|
133
|
+
self.class.decrement({:_id => id}, _args_for_counter(args), options)
|
122
134
|
end
|
123
135
|
|
124
136
|
def set(hash, options=nil)
|
@@ -130,7 +142,13 @@ module MongoMapper
|
|
130
142
|
end
|
131
143
|
|
132
144
|
def push_all(hash, options=nil)
|
133
|
-
|
145
|
+
Kernel.warn "push_all no longer supported. use $push with $each"
|
146
|
+
|
147
|
+
push_values = hash.inject({}) do |hsh, (key, values)|
|
148
|
+
{ key => { '$each' => values } }
|
149
|
+
end
|
150
|
+
|
151
|
+
self.class.push({:_id => id}, push_values, options)
|
134
152
|
end
|
135
153
|
|
136
154
|
def pull(hash, options=nil)
|
@@ -149,6 +167,14 @@ module MongoMapper
|
|
149
167
|
def pop(hash, options=nil)
|
150
168
|
self.class.pop({:_id => id}, hash, options)
|
151
169
|
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def _args_for_counter(args)
|
174
|
+
args.kind_of?(String) || args.kind_of?(Symbol) ?
|
175
|
+
{ args => 1 } :
|
176
|
+
args
|
177
|
+
end
|
152
178
|
end
|
153
179
|
end
|
154
180
|
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
module MongoMapper
|
2
|
+
module Plugins
|
3
|
+
module PartialUpdates
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
class PartialUpdatesDisabledError < StandardError; end
|
7
|
+
|
8
|
+
included do
|
9
|
+
class_attribute :partial_updates
|
10
|
+
self.partial_updates = false
|
11
|
+
|
12
|
+
self.after_find :_reset_partial_updates_callback
|
13
|
+
self.after_save :_reset_partial_updates_callback
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(*)
|
17
|
+
_reset_partial_updates_callback
|
18
|
+
super
|
19
|
+
end
|
20
|
+
|
21
|
+
def fields_for_partial_update
|
22
|
+
raise PartialUpdatesDisabledError if !partial_updates
|
23
|
+
|
24
|
+
Hash.new.tap do |hash|
|
25
|
+
attrs = _dealiased_attributes
|
26
|
+
|
27
|
+
hash[:set_fields] = Array.new.tap do |array|
|
28
|
+
attrs.each do |key, value|
|
29
|
+
if !@_last_saved_attributes.include?(key) ||
|
30
|
+
@_last_saved_attributes[key] != value
|
31
|
+
array << key
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
hash[:unset_fields] = @_last_saved_attributes.keys - attrs.keys
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def _reset_partial_updates_callback
|
43
|
+
_reset_attributes_for_partial_update if partial_updates
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def update(options={})
|
48
|
+
if partial_updates
|
49
|
+
super(options.merge(:persistence_method => :update))
|
50
|
+
else
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def save_to_collection(options={})
|
56
|
+
if partial_updates && options[:persistence_method] == :update
|
57
|
+
updates = fields_for_partial_update
|
58
|
+
|
59
|
+
set_fields = updates[:set_fields]
|
60
|
+
unset_fields = updates[:unset_fields]
|
61
|
+
|
62
|
+
if set_fields.any? || unset_fields.any?
|
63
|
+
set_fields.push("_id") if !set_fields.include?("_id")
|
64
|
+
end
|
65
|
+
|
66
|
+
options = options.merge({
|
67
|
+
:set_fields => set_fields,
|
68
|
+
:unset_fields => unset_fields
|
69
|
+
})
|
70
|
+
|
71
|
+
super(options)
|
72
|
+
else
|
73
|
+
super
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def _dealiased_attributes
|
78
|
+
self.class.dealias_keys(attributes)
|
79
|
+
end
|
80
|
+
|
81
|
+
def _reset_attributes_for_partial_update
|
82
|
+
@_last_saved_attributes = _dealiased_attributes._mongo_mapper_deep_copy_
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -39,7 +39,7 @@ module MongoMapper
|
|
39
39
|
if database_name.nil?
|
40
40
|
MongoMapper.database
|
41
41
|
else
|
42
|
-
connection.
|
42
|
+
connection.use(database_name).database
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
@@ -55,16 +55,21 @@ module MongoMapper
|
|
55
55
|
|
56
56
|
def collection
|
57
57
|
assert_supported
|
58
|
-
database.collection(collection_name)
|
58
|
+
database.collection(collection_name, collection_options)
|
59
59
|
end
|
60
60
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
def collection_options
|
62
|
+
{}
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def assert_supported
|
68
|
+
@embeddable ||= embeddable?
|
69
|
+
if @embeddable
|
70
|
+
raise MongoMapper::NotSupported.new('This is not supported for embeddable documents at this time.')
|
67
71
|
end
|
72
|
+
end
|
68
73
|
end
|
69
74
|
|
70
75
|
def collection
|
@@ -35,11 +35,12 @@ module MongoMapper
|
|
35
35
|
super(filter_protected_attrs(attrs))
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
38
|
+
protected
|
39
|
+
|
40
|
+
def filter_protected_attrs(attrs)
|
41
|
+
return attrs if protected_attributes.blank? || attrs.blank?
|
42
|
+
attrs.dup.delete_if { |key, val| protected_attributes.include?(key.to_sym) }
|
43
|
+
end
|
43
44
|
end
|
44
45
|
end
|
45
46
|
end
|
@@ -61,41 +61,42 @@ module MongoMapper
|
|
61
61
|
Plucky::CriteriaHash.new(criteria, :object_ids => object_id_keys)
|
62
62
|
end
|
63
63
|
|
64
|
-
|
65
|
-
def transformer
|
66
|
-
@transformer ||= lambda { |doc| load(doc) }
|
67
|
-
end
|
64
|
+
private
|
68
65
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
docs.flatten.each do |attrs|
|
73
|
-
doc = new(attrs)
|
74
|
-
yield(doc)
|
75
|
-
instances << doc
|
76
|
-
end
|
77
|
-
instances.size == 1 ? instances[0] : instances
|
78
|
-
end
|
66
|
+
def transformer
|
67
|
+
@transformer ||= lambda { |doc| load(doc) }
|
68
|
+
end
|
79
69
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
70
|
+
def initialize_each(*docs)
|
71
|
+
instances = []
|
72
|
+
docs = [{}] if docs.blank?
|
73
|
+
docs.flatten.each do |attrs|
|
74
|
+
doc = new(attrs)
|
75
|
+
yield(doc)
|
76
|
+
instances << doc
|
77
|
+
end
|
78
|
+
instances.size == 1 ? instances[0] : instances
|
79
|
+
end
|
84
80
|
|
85
|
-
|
86
|
-
|
87
|
-
|
81
|
+
def update_single(id, attrs)
|
82
|
+
if id.blank? || attrs.blank? || !attrs.is_a?(Hash)
|
83
|
+
raise ArgumentError, "Updating a single document requires an id and a hash of attributes"
|
88
84
|
end
|
89
85
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
86
|
+
find(id).tap do |doc|
|
87
|
+
doc.update_attributes(attrs)
|
88
|
+
end
|
89
|
+
end
|
94
90
|
|
95
|
-
|
96
|
-
|
97
|
-
|
91
|
+
def update_multiple(docs)
|
92
|
+
unless docs.is_a?(Hash)
|
93
|
+
raise ArgumentError, "Updating multiple documents takes 1 argument and it must be hash"
|
98
94
|
end
|
95
|
+
|
96
|
+
instances = []
|
97
|
+
docs.each_pair { |id, attrs| instances << update(id, attrs) }
|
98
|
+
instances
|
99
|
+
end
|
99
100
|
end
|
100
101
|
|
101
102
|
def save(options={})
|
@@ -116,25 +117,67 @@ module MongoMapper
|
|
116
117
|
self.class.delete(id).tap { @_destroyed = true } if persisted?
|
117
118
|
end
|
118
119
|
|
119
|
-
|
120
|
-
def create_or_update(options={})
|
121
|
-
result = persisted? ? update(options) : create(options)
|
122
|
-
result != false
|
123
|
-
end
|
120
|
+
private
|
124
121
|
|
125
|
-
|
126
|
-
|
127
|
-
|
122
|
+
def create_or_update(options={})
|
123
|
+
result = persisted? ? update(options) : create(options)
|
124
|
+
result != false
|
125
|
+
end
|
128
126
|
|
129
|
-
|
130
|
-
|
127
|
+
def create(options={})
|
128
|
+
save_to_collection(options.merge(:persistence_method => :insert))
|
129
|
+
end
|
130
|
+
|
131
|
+
def update(options={})
|
132
|
+
save_to_collection(options.reverse_merge(:persistence_method => :save))
|
133
|
+
end
|
134
|
+
|
135
|
+
def save_to_collection(options={})
|
136
|
+
@_new = false
|
137
|
+
method = options.delete(:persistence_method) || :save
|
138
|
+
update = to_mongo
|
139
|
+
query_options = Utils.get_safe_options(options)
|
140
|
+
|
141
|
+
if query_options.any?
|
142
|
+
collection = self.collection.with(write: query_options)
|
143
|
+
else
|
144
|
+
collection = self.collection
|
131
145
|
end
|
132
146
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
147
|
+
case method
|
148
|
+
when :insert
|
149
|
+
collection.insert_one(update, query_options)
|
150
|
+
when :save
|
151
|
+
collection.update_one({:_id => _id}, update, query_options.merge(upsert: true))
|
152
|
+
when :update
|
153
|
+
update.stringify_keys!
|
154
|
+
|
155
|
+
id = update.delete("_id")
|
156
|
+
|
157
|
+
set_values = update
|
158
|
+
unset_values = {}
|
159
|
+
|
160
|
+
if fields_for_set = options.delete(:set_fields)
|
161
|
+
set_values = set_values.slice(*fields_for_set)
|
162
|
+
end
|
163
|
+
|
164
|
+
if fields_for_unset = options.delete(:unset_fields)
|
165
|
+
fields_for_unset.each do |field|
|
166
|
+
unset_values[field] = true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
find_query = { :_id => id }
|
171
|
+
|
172
|
+
update_query = {}
|
173
|
+
update_query["$set"] = set_values if set_values.any?
|
174
|
+
update_query["$unset"] = unset_values if unset_values.any?
|
175
|
+
|
176
|
+
if update_query.any?
|
177
|
+
collection.update_one(find_query, update_query, query_options)
|
178
|
+
end
|
137
179
|
end
|
180
|
+
end
|
138
181
|
end
|
139
182
|
end
|
140
183
|
end
|