mongo_mapper 0.10.1 → 0.11.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/UPGRADES +3 -0
- data/examples/plugins.rb +2 -5
- data/lib/mongo_mapper.rb +1 -0
- data/lib/mongo_mapper/connection.rb +4 -0
- data/lib/mongo_mapper/embedded_document.rb +1 -0
- data/lib/mongo_mapper/extensions/object.rb +5 -6
- data/lib/mongo_mapper/plugins/accessible.rb +14 -16
- data/lib/mongo_mapper/plugins/associations.rb +21 -23
- data/lib/mongo_mapper/plugins/associations/base.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +4 -0
- data/lib/mongo_mapper/plugins/associations/many_association.rb +0 -4
- data/lib/mongo_mapper/plugins/associations/one_association.rb +1 -1
- data/lib/mongo_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
- data/lib/mongo_mapper/plugins/caching.rb +11 -13
- data/lib/mongo_mapper/plugins/callbacks.rb +12 -14
- data/lib/mongo_mapper/plugins/clone.rb +11 -13
- data/lib/mongo_mapper/plugins/dirty.rb +36 -38
- data/lib/mongo_mapper/plugins/document.rb +20 -22
- data/lib/mongo_mapper/plugins/embedded_callbacks.rb +11 -13
- data/lib/mongo_mapper/plugins/embedded_document.rb +22 -24
- data/lib/mongo_mapper/plugins/equality.rb +6 -8
- data/lib/mongo_mapper/plugins/identity_map.rb +11 -13
- data/lib/mongo_mapper/plugins/inspect.rb +6 -8
- data/lib/mongo_mapper/plugins/keys.rb +109 -110
- data/lib/mongo_mapper/plugins/logger.rb +2 -4
- data/lib/mongo_mapper/plugins/modifiers.rb +32 -34
- data/lib/mongo_mapper/plugins/persistence.rb +5 -7
- data/lib/mongo_mapper/plugins/protected.rb +14 -16
- data/lib/mongo_mapper/plugins/querying.rb +29 -31
- data/lib/mongo_mapper/plugins/rails.rb +28 -22
- data/lib/mongo_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
- data/lib/mongo_mapper/plugins/safe.rb +3 -5
- data/lib/mongo_mapper/plugins/sci.rb +3 -5
- data/lib/mongo_mapper/plugins/serialization.rb +49 -52
- data/lib/mongo_mapper/plugins/timestamps.rb +4 -6
- data/lib/mongo_mapper/plugins/validations.rb +8 -10
- data/lib/mongo_mapper/railtie/database.rake +1 -1
- data/lib/mongo_mapper/version.rb +1 -1
- data/lib/rails/generators/mongo_mapper/model/model_generator.rb +1 -1
- data/lib/rails/generators/mongo_mapper/model/templates/model.rb +2 -0
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +63 -0
- data/test/functional/associations/test_one_embedded_polymorphic_proxy.rb +208 -0
- data/test/functional/test_accessible.rb +5 -0
- data/test/functional/test_embedded_document.rb +12 -0
- data/test/functional/test_modifiers.rb +19 -19
- data/test/functional/test_protected.rb +10 -0
- data/test/functional/test_querying.rb +15 -1
- data/test/functional/test_validations.rb +33 -0
- data/test/models.rb +14 -0
- data/test/unit/associations/test_one_association.rb +11 -0
- data/test/unit/test_mongo_mapper.rb +9 -0
- data/test/unit/test_plugins.rb +2 -4
- data/test/unit/test_rails_reflect_on_association.rb +118 -0
- metadata +15 -11
@@ -57,14 +57,12 @@ module MongoMapper
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
60
|
+
def collection
|
61
|
+
_root_document.class.collection
|
62
|
+
end
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
end
|
64
|
+
def database
|
65
|
+
_root_document.class.database
|
68
66
|
end
|
69
67
|
end
|
70
68
|
end
|
@@ -23,25 +23,23 @@ module MongoMapper
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
def update_attributes(attrs={})
|
32
|
-
super(filter_protected_attrs(attrs))
|
33
|
-
end
|
26
|
+
def attributes=(attrs={})
|
27
|
+
super(filter_protected_attrs(attrs))
|
28
|
+
end
|
34
29
|
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
def update_attributes(attrs={})
|
31
|
+
super(filter_protected_attrs(attrs))
|
32
|
+
end
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
return attrs if protected_attributes.blank? || attrs.blank?
|
42
|
-
attrs.dup.delete_if { |key, val| protected_attributes.include?(key.to_sym) }
|
43
|
-
end
|
34
|
+
def update_attributes!(attrs={})
|
35
|
+
super(filter_protected_attrs(attrs))
|
44
36
|
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
def filter_protected_attrs(attrs)
|
40
|
+
return attrs if protected_attributes.blank? || attrs.blank?
|
41
|
+
attrs.dup.delete_if { |key, val| protected_attributes.include?(key.to_sym) }
|
42
|
+
end
|
45
43
|
end
|
46
44
|
end
|
47
45
|
end
|
@@ -137,44 +137,42 @@ module MongoMapper
|
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
end
|
140
|
+
def save(options={})
|
141
|
+
options.assert_valid_keys(:validate, :safe)
|
142
|
+
create_or_update(options)
|
143
|
+
end
|
145
144
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
145
|
+
def save!(options={})
|
146
|
+
options.assert_valid_keys(:safe)
|
147
|
+
save(options) || raise(DocumentNotValid.new(self))
|
148
|
+
end
|
150
149
|
|
151
|
-
|
152
|
-
|
153
|
-
|
150
|
+
def destroy
|
151
|
+
delete
|
152
|
+
end
|
154
153
|
|
155
|
-
|
156
|
-
|
157
|
-
|
154
|
+
def delete
|
155
|
+
self.class.delete(id).tap { @_destroyed = true } if persisted?
|
156
|
+
end
|
158
157
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
158
|
+
private
|
159
|
+
def create_or_update(options={})
|
160
|
+
result = persisted? ? update(options) : create(options)
|
161
|
+
result != false
|
162
|
+
end
|
164
163
|
|
165
|
-
|
166
|
-
|
167
|
-
|
164
|
+
def create(options={})
|
165
|
+
save_to_collection(options)
|
166
|
+
end
|
168
167
|
|
169
|
-
|
170
|
-
|
171
|
-
|
168
|
+
def update(options={})
|
169
|
+
save_to_collection(options)
|
170
|
+
end
|
172
171
|
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
end
|
172
|
+
def save_to_collection(options={})
|
173
|
+
@_new = false
|
174
|
+
collection.save(to_mongo, :safe => options[:safe])
|
175
|
+
end
|
178
176
|
end
|
179
177
|
end
|
180
178
|
end
|
@@ -2,36 +2,35 @@
|
|
2
2
|
module MongoMapper
|
3
3
|
module Plugins
|
4
4
|
module Rails
|
5
|
+
autoload :ActiveRecordAssociationAdapter, "mongo_mapper/plugins/rails/active_record_association_adapter"
|
5
6
|
extend ActiveSupport::Concern
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
8
|
+
def to_param
|
9
|
+
id.to_s if persisted?
|
10
|
+
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
def to_model
|
13
|
+
self
|
14
|
+
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
def to_key
|
17
|
+
[id] if persisted?
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def new_record?
|
21
|
+
new?
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def read_attribute(name)
|
25
|
+
self[name]
|
26
|
+
end
|
27
27
|
|
28
|
-
|
29
|
-
|
30
|
-
|
28
|
+
def read_attribute_before_type_cast(name)
|
29
|
+
read_key_before_type_cast(name)
|
30
|
+
end
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
end
|
32
|
+
def write_attribute(name, value)
|
33
|
+
self[name] = value
|
35
34
|
end
|
36
35
|
|
37
36
|
module ClassMethods
|
@@ -46,6 +45,13 @@ module MongoMapper
|
|
46
45
|
def column_names
|
47
46
|
keys.keys
|
48
47
|
end
|
48
|
+
|
49
|
+
# Returns returns an ActiveRecordAssociationAdapter for an association. This adapter has an API that is a
|
50
|
+
# subset of ActiveRecord::Reflection::AssociationReflection. This allows MongoMapper to be used with the
|
51
|
+
# association helpers in gems like simple_form and formtastic.
|
52
|
+
def reflect_on_association(name)
|
53
|
+
ActiveRecordAssociationAdapter.for_association(associations[name]) if associations[name]
|
54
|
+
end
|
49
55
|
end
|
50
56
|
end
|
51
57
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module MongoMapper
|
3
|
+
module Plugins
|
4
|
+
module Rails
|
5
|
+
class ActiveRecordAssociationAdapter
|
6
|
+
attr_reader :klass, :macro, :name, :options
|
7
|
+
|
8
|
+
def self.for_association(association)
|
9
|
+
macro = case association
|
10
|
+
when MongoMapper::Plugins::Associations::BelongsToAssociation
|
11
|
+
:belongs_to
|
12
|
+
when MongoMapper::Plugins::Associations::ManyAssociation
|
13
|
+
:has_many
|
14
|
+
when MongoMapper::Plugins::Associations::OneAssociation
|
15
|
+
:has_one
|
16
|
+
else
|
17
|
+
raise "no #{name} for association of type #{association.class}"
|
18
|
+
end
|
19
|
+
|
20
|
+
new(association, macro)
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize(association, macro)
|
24
|
+
@klass, @name = association.klass, association.name
|
25
|
+
# only include compatible options
|
26
|
+
@options = association.options.slice(:conditions, :order)
|
27
|
+
|
28
|
+
@macro = macro
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -19,11 +19,9 @@ module MongoMapper
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
super
|
26
|
-
end
|
22
|
+
def save_to_collection(options={})
|
23
|
+
options[:safe] = self.class.safe? unless options.key?(:safe)
|
24
|
+
super
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -27,11 +27,9 @@ module MongoMapper
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
write_key :_type, self.class.name if self.class.key?(:_type)
|
34
|
-
end
|
30
|
+
def initialize(*args)
|
31
|
+
super
|
32
|
+
write_key :_type, self.class.name if self.class.key?(:_type)
|
35
33
|
end
|
36
34
|
end
|
37
35
|
end
|
@@ -13,77 +13,74 @@ module MongoMapper
|
|
13
13
|
self.include_root_in_json = false
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
def serializable_hash(options = nil)
|
22
|
-
options ||= {}
|
16
|
+
def serializable_attributes
|
17
|
+
attributes.keys.map { |k| k.to_s } + ['id'] - ['_id']
|
18
|
+
end
|
23
19
|
|
24
|
-
|
25
|
-
|
20
|
+
def serializable_hash(options = nil)
|
21
|
+
options ||= {}
|
26
22
|
|
27
|
-
|
23
|
+
options[:only] = Array.wrap(options[:only]).map { |k| k.to_s }
|
24
|
+
options[:except] = Array.wrap(options[:except]).map { |k| k.to_s }
|
28
25
|
|
29
|
-
|
30
|
-
attribute_names &= options[:only]
|
31
|
-
elsif options[:except].any?
|
32
|
-
attribute_names -= options[:except]
|
33
|
-
end
|
26
|
+
attribute_names = serializable_attributes
|
34
27
|
|
35
|
-
|
36
|
-
|
37
|
-
|
28
|
+
if options[:only].any?
|
29
|
+
attribute_names &= options[:only]
|
30
|
+
elsif options[:except].any?
|
31
|
+
attribute_names -= options[:except]
|
32
|
+
end
|
38
33
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
value.map {|v| v.respond_to?(:serializable_hash) ? v.serializable_hash : v }
|
43
|
-
elsif value.respond_to?(:serializable_hash)
|
44
|
-
value.serializable_hash
|
45
|
-
else
|
46
|
-
value
|
47
|
-
end
|
48
|
-
hash
|
49
|
-
end
|
34
|
+
attribute_names += Array.wrap(options[:methods]).map { |m| m.to_s }.select do |method|
|
35
|
+
respond_to?(method)
|
36
|
+
end
|
50
37
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
38
|
+
hash = attribute_names.sort.inject({}) do |hash, name|
|
39
|
+
value = send(name)
|
40
|
+
hash[name] = if value.is_a?(Array)
|
41
|
+
value.map {|v| v.respond_to?(:serializable_hash) ? v.serializable_hash : v }
|
42
|
+
elsif value.respond_to?(:serializable_hash)
|
43
|
+
value.serializable_hash
|
44
|
+
else
|
45
|
+
value
|
55
46
|
end
|
56
|
-
|
57
47
|
hash
|
58
48
|
end
|
59
49
|
|
60
|
-
|
61
|
-
|
50
|
+
serializable_add_includes(options) do |association, records, opts|
|
51
|
+
hash[association.to_s] = records.is_a?(Array) ?
|
52
|
+
records.map { |r| r.serializable_hash(opts) } :
|
53
|
+
records.serializable_hash(opts)
|
62
54
|
end
|
63
55
|
|
64
|
-
|
56
|
+
hash
|
57
|
+
end
|
65
58
|
|
66
|
-
|
67
|
-
|
59
|
+
def to_xml(options = {}, &block)
|
60
|
+
XmlSerializer.new(self, options).serialize(&block)
|
61
|
+
end
|
68
62
|
|
69
|
-
|
70
|
-
:only => options[:only] }
|
63
|
+
private
|
71
64
|
|
72
|
-
|
73
|
-
|
65
|
+
def serializable_add_includes(options = {})
|
66
|
+
return unless include_associations = options.delete(:include)
|
74
67
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
yield(association, records, opts)
|
81
|
-
end
|
82
|
-
end
|
68
|
+
base_only_or_except = { :except => options[:except],
|
69
|
+
:only => options[:only] }
|
70
|
+
|
71
|
+
include_has_options = include_associations.is_a?(Hash)
|
72
|
+
associations = include_has_options ? include_associations.keys : Array.wrap(include_associations)
|
83
73
|
|
84
|
-
|
74
|
+
associations.each do |association|
|
75
|
+
records = get_proxy(self.class.associations[association])
|
76
|
+
unless records.nil?
|
77
|
+
association_options = include_has_options ? include_associations[association] : base_only_or_except
|
78
|
+
opts = options.merge(association_options)
|
79
|
+
yield(association, records, opts)
|
80
|
+
end
|
85
81
|
end
|
86
82
|
|
83
|
+
options[:include] = include_associations
|
87
84
|
end
|
88
85
|
|
89
86
|
module ClassMethods
|
@@ -12,12 +12,10 @@ module MongoMapper
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
self[:updated_at] = now
|
20
|
-
end
|
15
|
+
def update_timestamps
|
16
|
+
now = Time.now.utc
|
17
|
+
self[:created_at] = now if !persisted? && !created_at?
|
18
|
+
self[:updated_at] = now
|
21
19
|
end
|
22
20
|
end
|
23
21
|
end
|
@@ -17,16 +17,14 @@ module MongoMapper
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
20
|
+
def save(options = {})
|
21
|
+
options.reverse_merge!(:validate => true)
|
22
|
+
!options[:validate] || valid? ? super : false
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
25
|
+
def valid?(context = nil)
|
26
|
+
context ||= (new_record? ? :create : :update)
|
27
|
+
super(context)
|
30
28
|
end
|
31
29
|
|
32
30
|
class UniquenessValidator < ::ActiveModel::EachValidator
|
@@ -68,7 +66,7 @@ module MongoMapper
|
|
68
66
|
|
69
67
|
class AssociatedValidator < ::ActiveModel::EachValidator
|
70
68
|
def validate_each(record, attribute, value)
|
71
|
-
if !Array.wrap(value).all? { |c| c.nil? || c.valid? }
|
69
|
+
if !Array.wrap(value).all? { |c| c.nil? || c.valid?(options[:context]) }
|
72
70
|
record.errors.add(attribute, :invalid, :message => options[:message], :value => value)
|
73
71
|
end
|
74
72
|
end
|