mongo_mapper-unstable 2010.3.8 → 2010.06.23
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/README.rdoc +4 -8
- data/bin/mmconsole +1 -1
- data/examples/keys.rb +37 -0
- data/examples/plugins.rb +41 -0
- data/examples/querying.rb +35 -0
- data/examples/scopes.rb +52 -0
- data/lib/mongo_mapper/connection.rb +83 -0
- data/lib/mongo_mapper/document.rb +11 -329
- data/lib/mongo_mapper/embedded_document.rb +9 -38
- data/lib/mongo_mapper/exceptions.rb +30 -0
- data/lib/mongo_mapper/extensions/array.rb +19 -0
- data/lib/mongo_mapper/extensions/binary.rb +22 -0
- data/lib/mongo_mapper/extensions/boolean.rb +44 -0
- data/lib/mongo_mapper/extensions/date.rb +25 -0
- data/lib/mongo_mapper/extensions/float.rb +14 -0
- data/lib/mongo_mapper/extensions/hash.rb +14 -0
- data/lib/mongo_mapper/extensions/integer.rb +19 -0
- data/lib/mongo_mapper/extensions/kernel.rb +9 -0
- data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
- data/lib/mongo_mapper/extensions/object.rb +27 -0
- data/lib/mongo_mapper/extensions/object_id.rb +30 -0
- data/lib/mongo_mapper/extensions/set.rb +20 -0
- data/lib/mongo_mapper/extensions/string.rb +18 -0
- data/lib/mongo_mapper/extensions/time.rb +29 -0
- data/lib/mongo_mapper/plugins/accessible.rb +44 -0
- data/lib/mongo_mapper/plugins/associations/base.rb +7 -6
- data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +5 -6
- data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +5 -6
- data/lib/mongo_mapper/plugins/associations/collection.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +2 -1
- data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +25 -39
- data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +4 -4
- data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +36 -46
- data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +5 -4
- data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +1 -0
- data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +40 -0
- data/lib/mongo_mapper/plugins/associations/one_proxy.rb +7 -7
- data/lib/mongo_mapper/plugins/associations/proxy.rb +16 -8
- data/lib/mongo_mapper/plugins/associations.rb +14 -22
- data/lib/mongo_mapper/plugins/caching.rb +21 -0
- data/lib/mongo_mapper/plugins/callbacks.rb +17 -5
- data/lib/mongo_mapper/plugins/clone.rb +10 -4
- data/lib/mongo_mapper/plugins/descendants.rb +3 -2
- data/lib/mongo_mapper/plugins/dirty.rb +1 -0
- data/lib/mongo_mapper/plugins/document.rb +41 -0
- data/lib/mongo_mapper/{support/find.rb → plugins/dynamic_querying/dynamic_finder.rb} +3 -36
- data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
- data/lib/mongo_mapper/plugins/embedded_document.rb +49 -0
- data/lib/mongo_mapper/plugins/equality.rb +4 -10
- data/lib/mongo_mapper/plugins/identity_map.rb +29 -23
- data/lib/mongo_mapper/plugins/indexes.rb +12 -0
- data/lib/mongo_mapper/plugins/inspect.rb +1 -0
- data/lib/mongo_mapper/plugins/keys/key.rb +55 -0
- data/lib/mongo_mapper/plugins/keys.rb +85 -110
- data/lib/mongo_mapper/plugins/logger.rb +1 -0
- data/lib/mongo_mapper/plugins/modifiers.rb +41 -16
- data/lib/mongo_mapper/plugins/pagination.rb +5 -15
- data/lib/mongo_mapper/plugins/persistence.rb +69 -0
- data/lib/mongo_mapper/plugins/protected.rb +9 -1
- data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
- data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
- data/lib/mongo_mapper/plugins/querying.rb +176 -0
- data/lib/mongo_mapper/plugins/rails.rb +6 -1
- data/lib/mongo_mapper/plugins/safe.rb +28 -0
- data/lib/mongo_mapper/plugins/sci.rb +32 -0
- data/lib/mongo_mapper/plugins/scopes.rb +21 -0
- data/lib/mongo_mapper/plugins/serialization.rb +5 -4
- data/lib/mongo_mapper/plugins/timestamps.rb +2 -1
- data/lib/mongo_mapper/plugins/userstamps.rb +1 -0
- data/lib/mongo_mapper/plugins/validations.rb +9 -5
- data/lib/mongo_mapper/plugins.rb +1 -20
- data/lib/mongo_mapper/support/descendant_appends.rb +5 -6
- data/lib/mongo_mapper/version.rb +4 -0
- data/lib/mongo_mapper.rb +71 -128
- data/test/{NOTE_ON_TESTING → _NOTE_ON_TESTING} +0 -0
- data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +5 -5
- data/test/functional/associations/test_belongs_to_proxy.rb +13 -21
- data/test/functional/associations/test_in_array_proxy.rb +7 -9
- data/test/functional/associations/test_many_documents_as_proxy.rb +5 -5
- data/test/functional/associations/test_many_documents_proxy.rb +186 -64
- data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +22 -22
- data/test/functional/associations/test_many_embedded_proxy.rb +32 -32
- data/test/functional/associations/test_many_polymorphic_proxy.rb +47 -47
- data/test/functional/associations/test_one_embedded_proxy.rb +67 -0
- data/test/functional/associations/test_one_proxy.rb +70 -49
- data/test/functional/test_accessible.rb +168 -0
- data/test/functional/test_associations.rb +11 -11
- data/test/functional/test_binary.rb +5 -5
- data/test/functional/test_caching.rb +76 -0
- data/test/functional/test_callbacks.rb +104 -34
- data/test/functional/test_dirty.rb +16 -16
- data/test/functional/test_document.rb +12 -924
- data/test/functional/test_dynamic_querying.rb +75 -0
- data/test/functional/test_embedded_document.rb +88 -8
- data/test/functional/test_identity_map.rb +41 -43
- data/test/functional/{test_indexing.rb → test_indexes.rb} +3 -5
- data/test/functional/test_logger.rb +1 -1
- data/test/functional/test_modifiers.rb +275 -181
- data/test/functional/test_pagination.rb +13 -15
- data/test/functional/test_protected.rb +25 -11
- data/test/functional/test_querying.rb +873 -0
- data/test/functional/test_safe.rb +76 -0
- data/test/functional/test_sci.rb +230 -0
- data/test/functional/test_scopes.rb +171 -0
- data/test/functional/test_string_id_compatibility.rb +11 -11
- data/test/functional/test_timestamps.rb +0 -2
- data/test/functional/test_userstamps.rb +0 -1
- data/test/functional/test_validations.rb +44 -31
- data/test/models.rb +18 -17
- data/test/{active_model_lint_test.rb → test_active_model_lint.rb} +3 -1
- data/test/test_helper.rb +59 -16
- data/test/unit/associations/test_base.rb +47 -42
- data/test/unit/associations/test_proxy.rb +15 -15
- data/test/unit/serializers/test_json_serializer.rb +29 -29
- data/test/unit/test_clone.rb +69 -0
- data/test/unit/test_descendant_appends.rb +3 -3
- data/test/unit/test_document.rb +49 -67
- data/test/unit/test_dynamic_finder.rb +53 -51
- data/test/unit/test_embedded_document.rb +19 -38
- data/test/unit/{test_support.rb → test_extensions.rb} +136 -122
- data/test/unit/test_key.rb +185 -0
- data/test/unit/test_keys.rb +29 -147
- data/test/unit/test_mongo_mapper.rb +3 -48
- data/test/unit/test_pagination.rb +1 -150
- data/test/unit/test_rails.rb +77 -19
- data/test/unit/test_rails_compatibility.rb +12 -12
- data/test/unit/test_serialization.rb +5 -5
- data/test/unit/test_time_zones.rb +9 -9
- data/test/unit/test_validations.rb +46 -46
- metadata +157 -155
- data/.gitignore +0 -10
- data/Rakefile +0 -55
- data/VERSION +0 -1
- data/lib/mongo_mapper/plugins/pagination/proxy.rb +0 -72
- data/lib/mongo_mapper/query.rb +0 -130
- data/lib/mongo_mapper/support.rb +0 -215
- data/mongo_mapper.gemspec +0 -196
- data/performance/read_write.rb +0 -52
- data/specs.watchr +0 -51
- data/test/support/custom_matchers.rb +0 -55
- data/test/support/timing.rb +0 -16
- data/test/unit/test_query.rb +0 -340
@@ -1,57 +1,36 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Associations
|
4
5
|
class InArrayProxy < Collection
|
5
|
-
include
|
6
|
+
include DynamicQuerying::ClassMethods
|
6
7
|
|
7
8
|
def find(*args)
|
8
|
-
|
9
|
-
|
10
|
-
case args.first
|
11
|
-
when :first
|
12
|
-
first(options)
|
13
|
-
when :last
|
14
|
-
last(options)
|
15
|
-
when :all
|
16
|
-
all(options)
|
17
|
-
else
|
18
|
-
klass.find(*scoped_ids(args) << scoped_options(options))
|
19
|
-
end
|
9
|
+
query.find(*scoped_ids(args))
|
20
10
|
end
|
21
11
|
|
22
12
|
def find!(*args)
|
23
|
-
|
24
|
-
|
25
|
-
case args.first
|
26
|
-
when :first
|
27
|
-
first(options)
|
28
|
-
when :last
|
29
|
-
last(options)
|
30
|
-
when :all
|
31
|
-
all(options)
|
32
|
-
else
|
33
|
-
klass.find!(*scoped_ids(args) << scoped_options(options))
|
34
|
-
end
|
13
|
+
query.find!(*scoped_ids(args))
|
35
14
|
end
|
36
15
|
|
37
16
|
def paginate(options)
|
38
|
-
|
17
|
+
query.paginate(options)
|
39
18
|
end
|
40
19
|
|
41
20
|
def all(options={})
|
42
|
-
|
21
|
+
query(options).all
|
43
22
|
end
|
44
23
|
|
45
24
|
def first(options={})
|
46
|
-
|
25
|
+
query(options).first
|
47
26
|
end
|
48
27
|
|
49
28
|
def last(options={})
|
50
|
-
|
29
|
+
query(options).last
|
51
30
|
end
|
52
31
|
|
53
32
|
def count(options={})
|
54
|
-
options.blank? ? ids.size :
|
33
|
+
options.blank? ? ids.size : query(options).count
|
55
34
|
end
|
56
35
|
|
57
36
|
def destroy_all(options={})
|
@@ -63,7 +42,7 @@ module MongoMapper
|
|
63
42
|
end
|
64
43
|
|
65
44
|
def delete_all(options={})
|
66
|
-
docs =
|
45
|
+
docs = query(options).fields(:_id).all
|
67
46
|
docs.each { |doc| ids.delete(doc.id) }
|
68
47
|
klass.delete(docs.map(&:id))
|
69
48
|
reset
|
@@ -78,7 +57,7 @@ module MongoMapper
|
|
78
57
|
doc = klass.create(attrs)
|
79
58
|
unless doc.new?
|
80
59
|
ids << doc.id
|
81
|
-
|
60
|
+
proxy_owner.save
|
82
61
|
reset
|
83
62
|
end
|
84
63
|
doc
|
@@ -88,7 +67,7 @@ module MongoMapper
|
|
88
67
|
doc = klass.create!(attrs)
|
89
68
|
unless doc.new?
|
90
69
|
ids << doc.id
|
91
|
-
|
70
|
+
proxy_owner.save
|
92
71
|
reset
|
93
72
|
end
|
94
73
|
doc
|
@@ -116,16 +95,23 @@ module MongoMapper
|
|
116
95
|
end
|
117
96
|
|
118
97
|
private
|
119
|
-
def
|
120
|
-
|
98
|
+
def query(options={})
|
99
|
+
klass.
|
100
|
+
query(association.query_options).
|
101
|
+
update(options).
|
102
|
+
update(criteria)
|
121
103
|
end
|
122
104
|
|
123
|
-
def
|
124
|
-
|
105
|
+
def criteria
|
106
|
+
{:_id => ids}
|
125
107
|
end
|
126
108
|
|
127
109
|
def scoped_ids(args)
|
128
|
-
args.flatten.
|
110
|
+
valid = args.flatten.select do |id|
|
111
|
+
id = ObjectId.to_mongo(id) if klass.using_object_id?
|
112
|
+
ids.include?(id)
|
113
|
+
end
|
114
|
+
valid.empty? ? nil : valid
|
129
115
|
end
|
130
116
|
|
131
117
|
def find_target
|
@@ -133,7 +119,7 @@ module MongoMapper
|
|
133
119
|
end
|
134
120
|
|
135
121
|
def ids
|
136
|
-
|
122
|
+
proxy_owner[options[:in]]
|
137
123
|
end
|
138
124
|
end
|
139
125
|
end
|
@@ -1,16 +1,16 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Associations
|
4
5
|
class ManyDocumentsAsProxy < ManyDocumentsProxy
|
5
6
|
protected
|
6
|
-
def
|
7
|
-
{type_key_name =>
|
7
|
+
def criteria
|
8
|
+
{type_key_name => proxy_owner.class.name, id_key_name => proxy_owner.id}
|
8
9
|
end
|
9
10
|
|
10
11
|
def apply_scope(doc)
|
11
12
|
ensure_owner_saved
|
12
|
-
doc[
|
13
|
-
doc[id_key_name] = owner.id
|
13
|
+
criteria.each { |key, value| doc[key] = value }
|
14
14
|
doc
|
15
15
|
end
|
16
16
|
|
@@ -1,49 +1,21 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Associations
|
4
5
|
class ManyDocumentsProxy < Collection
|
5
|
-
include
|
6
|
-
|
7
|
-
def find(*args)
|
8
|
-
options = args.extract_options!
|
9
|
-
klass.find(*args << scoped_options(options))
|
10
|
-
end
|
11
|
-
|
12
|
-
def find!(*args)
|
13
|
-
options = args.extract_options!
|
14
|
-
klass.find!(*args << scoped_options(options))
|
15
|
-
end
|
16
|
-
|
17
|
-
def paginate(options)
|
18
|
-
klass.paginate(scoped_options(options))
|
19
|
-
end
|
20
|
-
|
21
|
-
def all(options={})
|
22
|
-
klass.all(scoped_options(options))
|
23
|
-
end
|
24
|
-
|
25
|
-
def first(options={})
|
26
|
-
klass.first(scoped_options(options))
|
27
|
-
end
|
28
|
-
|
29
|
-
def last(options={})
|
30
|
-
klass.last(scoped_options(options))
|
31
|
-
end
|
32
|
-
|
33
|
-
def count(options={})
|
34
|
-
klass.count(scoped_options(options))
|
35
|
-
end
|
6
|
+
include DynamicQuerying::ClassMethods
|
7
|
+
include Querying::PluckyMethods
|
36
8
|
|
37
9
|
def replace(docs)
|
38
10
|
load_target
|
39
11
|
target.map(&:destroy)
|
40
|
-
docs.each { |doc|
|
12
|
+
docs.each { |doc| prepare(doc).save }
|
41
13
|
reset
|
42
14
|
end
|
43
15
|
|
44
16
|
def <<(*docs)
|
45
17
|
ensure_owner_saved
|
46
|
-
flatten_deeper(docs).each { |doc|
|
18
|
+
flatten_deeper(docs).each { |doc| prepare(doc).save }
|
47
19
|
reset
|
48
20
|
end
|
49
21
|
alias_method :push, :<<
|
@@ -52,7 +24,8 @@ module MongoMapper
|
|
52
24
|
def build(attrs={})
|
53
25
|
doc = klass.new(attrs)
|
54
26
|
apply_scope(doc)
|
55
|
-
|
27
|
+
@target ||= [] unless loaded?
|
28
|
+
@target << doc
|
56
29
|
doc
|
57
30
|
end
|
58
31
|
|
@@ -76,25 +49,38 @@ module MongoMapper
|
|
76
49
|
end
|
77
50
|
|
78
51
|
def delete_all(options={})
|
79
|
-
|
52
|
+
query(options).remove
|
80
53
|
reset
|
81
54
|
end
|
82
55
|
|
83
56
|
def nullify
|
84
|
-
|
85
|
-
all(criteria).each do |doc|
|
86
|
-
doc.update_attributes(self.foreign_key => nil)
|
87
|
-
end
|
57
|
+
all.each { |doc| doc.update_attributes(self.foreign_key => nil) }
|
88
58
|
reset
|
89
59
|
end
|
90
60
|
|
61
|
+
def save_to_collection(options={})
|
62
|
+
@target.each { |doc| doc.save(options) } if @target
|
63
|
+
end
|
64
|
+
|
91
65
|
protected
|
92
|
-
def
|
93
|
-
|
66
|
+
def query(options={})
|
67
|
+
klass.
|
68
|
+
query(association.query_options).
|
69
|
+
update(options).update(criteria)
|
70
|
+
end
|
71
|
+
|
72
|
+
def method_missing(method, *args, &block)
|
73
|
+
if klass.respond_to?(method)
|
74
|
+
result = klass.send(method, *args, &block)
|
75
|
+
result.is_a?(Plucky::Query) ?
|
76
|
+
query.merge(result) : super
|
77
|
+
else
|
78
|
+
super
|
79
|
+
end
|
94
80
|
end
|
95
81
|
|
96
|
-
def
|
97
|
-
|
82
|
+
def criteria
|
83
|
+
{self.foreign_key => proxy_owner.id}
|
98
84
|
end
|
99
85
|
|
100
86
|
def find_target
|
@@ -102,17 +88,21 @@ module MongoMapper
|
|
102
88
|
end
|
103
89
|
|
104
90
|
def ensure_owner_saved
|
105
|
-
|
91
|
+
proxy_owner.save if proxy_owner.new?
|
92
|
+
end
|
93
|
+
|
94
|
+
def prepare(doc)
|
95
|
+
klass === doc ? apply_scope(doc) : build(doc)
|
106
96
|
end
|
107
97
|
|
108
98
|
def apply_scope(doc)
|
109
99
|
ensure_owner_saved
|
110
|
-
doc[
|
100
|
+
criteria.each { |key, value| doc[key] = value }
|
111
101
|
doc
|
112
102
|
end
|
113
103
|
|
114
104
|
def foreign_key
|
115
|
-
options[:foreign_key] ||
|
105
|
+
options[:foreign_key] || proxy_owner.class.name.to_s.underscore.gsub("/", "_") + "_id"
|
116
106
|
end
|
117
107
|
end
|
118
108
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Associations
|
@@ -11,10 +12,10 @@ module MongoMapper
|
|
11
12
|
|
12
13
|
private
|
13
14
|
def find_target
|
14
|
-
(@_values || []).map do |
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
(@_values || []).map do |attrs|
|
16
|
+
klass.load(attrs).tap do |child|
|
17
|
+
assign_references(child)
|
18
|
+
end
|
18
19
|
end
|
19
20
|
end
|
20
21
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module MongoMapper
|
3
|
+
module Plugins
|
4
|
+
module Associations
|
5
|
+
class OneEmbeddedProxy < Proxy
|
6
|
+
def build(attributes={})
|
7
|
+
@target = klass.new(attributes)
|
8
|
+
assign_references(@target)
|
9
|
+
loaded
|
10
|
+
@target
|
11
|
+
end
|
12
|
+
|
13
|
+
def replace(doc)
|
14
|
+
if doc.respond_to?(:attributes)
|
15
|
+
@target = klass.load(doc.attributes)
|
16
|
+
else
|
17
|
+
@target = klass.load(doc)
|
18
|
+
end
|
19
|
+
assign_references(@target)
|
20
|
+
loaded
|
21
|
+
@target
|
22
|
+
end
|
23
|
+
|
24
|
+
protected
|
25
|
+
|
26
|
+
def find_target
|
27
|
+
if @value
|
28
|
+
klass.load(@value).tap do |child|
|
29
|
+
assign_references(child)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def assign_references(doc)
|
35
|
+
doc._parent_document = proxy_owner if doc
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,9 +1,8 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Associations
|
4
5
|
class OneProxy < Proxy
|
5
|
-
undef_method :object_id
|
6
|
-
|
7
6
|
def build(attrs={})
|
8
7
|
instantiate_target(:new, attrs)
|
9
8
|
end
|
@@ -36,8 +35,9 @@ module MongoMapper
|
|
36
35
|
reset
|
37
36
|
|
38
37
|
unless doc.nil?
|
39
|
-
|
40
|
-
doc
|
38
|
+
proxy_owner.save if proxy_owner.new?
|
39
|
+
doc = klass.new(doc) unless klass === doc
|
40
|
+
doc[foreign_key] = proxy_owner.id
|
41
41
|
doc.save if doc.new?
|
42
42
|
loaded
|
43
43
|
@target = doc
|
@@ -46,11 +46,11 @@ module MongoMapper
|
|
46
46
|
|
47
47
|
protected
|
48
48
|
def find_target
|
49
|
-
target_class.first(association.query_options.merge(foreign_key =>
|
49
|
+
target_class.first(association.query_options.merge(foreign_key => proxy_owner.id))
|
50
50
|
end
|
51
51
|
|
52
52
|
def instantiate_target(instantiator, attrs={})
|
53
|
-
@target = target_class.send(instantiator, attrs.update(foreign_key =>
|
53
|
+
@target = target_class.send(instantiator, attrs.update(foreign_key => proxy_owner.id))
|
54
54
|
loaded
|
55
55
|
@target
|
56
56
|
end
|
@@ -60,7 +60,7 @@ module MongoMapper
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def foreign_key
|
63
|
-
options[:foreign_key] ||
|
63
|
+
options[:foreign_key] || proxy_owner.class.name.foreign_key
|
64
64
|
end
|
65
65
|
end
|
66
66
|
end
|
@@ -1,24 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'forwardable'
|
1
3
|
module MongoMapper
|
2
4
|
module Plugins
|
3
5
|
module Associations
|
4
6
|
class Proxy
|
7
|
+
extend Forwardable
|
8
|
+
|
5
9
|
alias :proxy_respond_to? :respond_to?
|
6
10
|
alias :proxy_extend :extend
|
7
11
|
|
8
12
|
instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
|
9
13
|
|
10
|
-
attr_reader :
|
14
|
+
attr_reader :proxy_owner, :association, :target
|
11
15
|
|
12
|
-
alias :proxy_owner :owner
|
13
16
|
alias :proxy_target :target
|
14
17
|
alias :proxy_association :association
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
delegate :collection, :to => :klass
|
19
|
+
def_delegators :proxy_association, :klass, :options
|
20
|
+
def_delegator :klass, :collection
|
19
21
|
|
20
22
|
def initialize(owner, association)
|
21
|
-
@
|
23
|
+
@proxy_owner, @association, @loaded = owner, association, false
|
22
24
|
Array(association.options[:extend]).each { |ext| proxy_extend(ext) }
|
23
25
|
reset
|
24
26
|
end
|
@@ -96,8 +98,14 @@ module MongoMapper
|
|
96
98
|
end
|
97
99
|
|
98
100
|
def load_target
|
99
|
-
|
100
|
-
|
101
|
+
unless loaded?
|
102
|
+
if @target.is_a?(Array) && @target.any?
|
103
|
+
@target = find_target + @target.find_all { |record| record.new? }
|
104
|
+
else
|
105
|
+
@target = find_target
|
106
|
+
end
|
107
|
+
loaded
|
108
|
+
end
|
101
109
|
@target
|
102
110
|
rescue MongoMapper::DocumentNotFound
|
103
111
|
reset
|
@@ -1,7 +1,13 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Associations
|
4
5
|
module ClassMethods
|
6
|
+
def inherited(subclass)
|
7
|
+
subclass.associations = associations.dup
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
5
11
|
def belongs_to(association_id, options={}, &extension)
|
6
12
|
create_association(:belongs_to, association_id, options, &extension)
|
7
13
|
end
|
@@ -22,11 +28,6 @@ module MongoMapper
|
|
22
28
|
@associations = hash
|
23
29
|
end
|
24
30
|
|
25
|
-
def inherited(subclass)
|
26
|
-
subclass.associations = associations.dup
|
27
|
-
super
|
28
|
-
end
|
29
|
-
|
30
31
|
private
|
31
32
|
def create_association(type, name, options, &extension)
|
32
33
|
association = Associations::Base.new(type, name, options, &extension)
|
@@ -67,7 +68,6 @@ module MongoMapper
|
|
67
68
|
self.class.associations
|
68
69
|
end
|
69
70
|
|
70
|
-
# @api private?
|
71
71
|
def embedded_associations
|
72
72
|
associations.select do |name, association|
|
73
73
|
association.embeddable?
|
@@ -81,25 +81,17 @@ module MongoMapper
|
|
81
81
|
proxy = association.proxy_class.new(self, association)
|
82
82
|
self.instance_variable_set(association.ivar, proxy)
|
83
83
|
end
|
84
|
-
|
85
84
|
proxy
|
86
85
|
end
|
87
|
-
end
|
88
86
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
autoload :ManyEmbeddedPolymorphicProxy, 'mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy'
|
98
|
-
autoload :ManyDocumentsAsProxy, 'mongo_mapper/plugins/associations/many_documents_as_proxy'
|
99
|
-
autoload :OneProxy, 'mongo_mapper/plugins/associations/one_proxy'
|
100
|
-
autoload :InArrayProxy, 'mongo_mapper/plugins/associations/in_array_proxy'
|
87
|
+
def save_to_collection(options={})
|
88
|
+
super
|
89
|
+
associations.each do |association_name, association|
|
90
|
+
proxy = get_proxy(association)
|
91
|
+
proxy.save_to_collection(options) if proxy.proxy_respond_to?(:save_to_collection)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
101
95
|
end
|
102
96
|
end
|
103
97
|
end
|
104
|
-
|
105
|
-
require 'mongo_mapper/plugins/associations/proxy'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module MongoMapper
|
3
|
+
module Plugins
|
4
|
+
module Caching
|
5
|
+
module InstanceMethods
|
6
|
+
def cache_key(*suffixes)
|
7
|
+
cache_key = case
|
8
|
+
when new?
|
9
|
+
"#{self.class.name}/new"
|
10
|
+
when timestamp = self[:updated_at]
|
11
|
+
"#{self.class.name}/#{id}-#{timestamp.to_s(:number)}"
|
12
|
+
else
|
13
|
+
"#{self.class.name}/#{id}"
|
14
|
+
end
|
15
|
+
cache_key += "/#{suffixes.join('/')}" unless suffixes.empty?
|
16
|
+
cache_key
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# Almost all of this callback stuff is pulled directly from ActiveSupport
|
2
3
|
# in the interest of support rails 2 and 3 at the same time and is the
|
3
4
|
# same copyright as rails.
|
@@ -76,8 +77,19 @@ module MongoMapper
|
|
76
77
|
result
|
77
78
|
end
|
78
79
|
|
79
|
-
def run_callbacks(kind, options
|
80
|
-
|
80
|
+
def run_callbacks(kind, options={}, &block)
|
81
|
+
callback_chain_method = "#{kind}_callback_chain"
|
82
|
+
return unless self.class.respond_to?(callback_chain_method)
|
83
|
+
self.class.send(callback_chain_method).run(self, options, &block)
|
84
|
+
self.embedded_associations.each do |association|
|
85
|
+
if association.one?
|
86
|
+
self.send(association.name).run_callbacks(kind, options, &block)
|
87
|
+
else
|
88
|
+
self.send(association.name).each do |document|
|
89
|
+
document.run_callbacks(kind, options, &block)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
81
93
|
end
|
82
94
|
|
83
95
|
private
|
@@ -111,7 +123,7 @@ module MongoMapper
|
|
111
123
|
new(methods)
|
112
124
|
end
|
113
125
|
|
114
|
-
def run(object, options
|
126
|
+
def run(object, options={}, &terminator)
|
115
127
|
enumerator = options[:enumerator] || :each
|
116
128
|
|
117
129
|
unless block_given?
|
@@ -158,7 +170,7 @@ module MongoMapper
|
|
158
170
|
class Callback
|
159
171
|
attr_reader :kind, :method, :identifier, :options
|
160
172
|
|
161
|
-
def initialize(kind, method, options
|
173
|
+
def initialize(kind, method, options={})
|
162
174
|
@kind = kind
|
163
175
|
@method = method
|
164
176
|
@identifier = options[:identifier]
|
@@ -226,4 +238,4 @@ module MongoMapper
|
|
226
238
|
end
|
227
239
|
end
|
228
240
|
end
|
229
|
-
end
|
241
|
+
end
|
@@ -1,11 +1,17 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Clone
|
4
5
|
module InstanceMethods
|
5
|
-
def
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
def initialize_copy(other)
|
7
|
+
@_new = true
|
8
|
+
@_destroyed = false
|
9
|
+
default_id_value({})
|
10
|
+
self.attributes = other.attributes.clone.except(:_id).inject({}) do |hash, entry|
|
11
|
+
key, value = entry
|
12
|
+
hash[key] = value.duplicable? ? value.clone : value
|
13
|
+
hash
|
14
|
+
end
|
9
15
|
end
|
10
16
|
end
|
11
17
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
module MongoMapper
|
2
3
|
module Plugins
|
3
4
|
module Descendants
|
4
5
|
module ClassMethods
|
5
6
|
def inherited(descendant)
|
6
|
-
|
7
|
+
descendants << descendant
|
7
8
|
super
|
8
9
|
end
|
9
10
|
|
10
11
|
def descendants
|
11
|
-
@descendants
|
12
|
+
@descendants ||= []
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
module MongoMapper
|
3
|
+
module Plugins
|
4
|
+
module Document
|
5
|
+
module ClassMethods
|
6
|
+
def embeddable?
|
7
|
+
false
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module InstanceMethods
|
12
|
+
def new?
|
13
|
+
@_new
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroyed?
|
17
|
+
@_destroyed == true
|
18
|
+
end
|
19
|
+
|
20
|
+
def reload
|
21
|
+
if doc = collection.find_one(:_id => id)
|
22
|
+
tap do |instance|
|
23
|
+
instance.class.associations.each_key do |association_name|
|
24
|
+
send(association_name).reset if respond_to?(association_name)
|
25
|
+
end
|
26
|
+
instance.attributes = doc
|
27
|
+
end
|
28
|
+
else
|
29
|
+
raise DocumentNotFound, "Document match #{_id.inspect} does not exist in #{collection.name} collection"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Used by embedded docs to find root easily without if/respond_to? stuff.
|
34
|
+
# Documents are always root documents.
|
35
|
+
def _root_document
|
36
|
+
self
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|