jonbell-mongo_mapper 0.8.6

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.
Files changed (145) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +33 -0
  3. data/UPGRADES +7 -0
  4. data/bin/mmconsole +60 -0
  5. data/examples/attr_accessible.rb +22 -0
  6. data/examples/attr_protected.rb +22 -0
  7. data/examples/cache_key.rb +24 -0
  8. data/examples/custom_types.rb +24 -0
  9. data/examples/identity_map.rb +33 -0
  10. data/examples/identity_map/automatic.rb +8 -0
  11. data/examples/identity_map/middleware.rb +14 -0
  12. data/examples/keys.rb +40 -0
  13. data/examples/modifiers/set.rb +25 -0
  14. data/examples/plugins.rb +41 -0
  15. data/examples/querying.rb +35 -0
  16. data/examples/safe.rb +43 -0
  17. data/examples/scopes.rb +52 -0
  18. data/examples/validating/embedded_docs.rb +29 -0
  19. data/lib/mongo_mapper.rb +79 -0
  20. data/lib/mongo_mapper/connection.rb +83 -0
  21. data/lib/mongo_mapper/document.rb +41 -0
  22. data/lib/mongo_mapper/embedded_document.rb +31 -0
  23. data/lib/mongo_mapper/exceptions.rb +27 -0
  24. data/lib/mongo_mapper/extensions/array.rb +19 -0
  25. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  26. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  27. data/lib/mongo_mapper/extensions/date.rb +25 -0
  28. data/lib/mongo_mapper/extensions/float.rb +14 -0
  29. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  30. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  31. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  32. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  33. data/lib/mongo_mapper/extensions/object.rb +27 -0
  34. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  35. data/lib/mongo_mapper/extensions/set.rb +20 -0
  36. data/lib/mongo_mapper/extensions/string.rb +18 -0
  37. data/lib/mongo_mapper/extensions/time.rb +29 -0
  38. data/lib/mongo_mapper/plugins.rb +15 -0
  39. data/lib/mongo_mapper/plugins/accessible.rb +44 -0
  40. data/lib/mongo_mapper/plugins/associations.rb +97 -0
  41. data/lib/mongo_mapper/plugins/associations/base.rb +124 -0
  42. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +29 -0
  43. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +24 -0
  44. data/lib/mongo_mapper/plugins/associations/collection.rb +27 -0
  45. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +40 -0
  46. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +127 -0
  47. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  48. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +109 -0
  49. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  50. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  51. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  52. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +40 -0
  53. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  54. data/lib/mongo_mapper/plugins/associations/proxy.rb +139 -0
  55. data/lib/mongo_mapper/plugins/caching.rb +21 -0
  56. data/lib/mongo_mapper/plugins/callbacks.rb +241 -0
  57. data/lib/mongo_mapper/plugins/clone.rb +22 -0
  58. data/lib/mongo_mapper/plugins/descendants.rb +17 -0
  59. data/lib/mongo_mapper/plugins/dirty.rb +124 -0
  60. data/lib/mongo_mapper/plugins/document.rb +41 -0
  61. data/lib/mongo_mapper/plugins/dynamic_querying.rb +43 -0
  62. data/lib/mongo_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  63. data/lib/mongo_mapper/plugins/embedded_document.rb +48 -0
  64. data/lib/mongo_mapper/plugins/equality.rb +17 -0
  65. data/lib/mongo_mapper/plugins/identity_map.rb +128 -0
  66. data/lib/mongo_mapper/plugins/indexes.rb +12 -0
  67. data/lib/mongo_mapper/plugins/inspect.rb +15 -0
  68. data/lib/mongo_mapper/plugins/keys.rb +313 -0
  69. data/lib/mongo_mapper/plugins/keys/key.rb +59 -0
  70. data/lib/mongo_mapper/plugins/logger.rb +18 -0
  71. data/lib/mongo_mapper/plugins/modifiers.rb +112 -0
  72. data/lib/mongo_mapper/plugins/pagination.rb +14 -0
  73. data/lib/mongo_mapper/plugins/persistence.rb +69 -0
  74. data/lib/mongo_mapper/plugins/protected.rb +53 -0
  75. data/lib/mongo_mapper/plugins/querying.rb +176 -0
  76. data/lib/mongo_mapper/plugins/querying/decorator.rb +46 -0
  77. data/lib/mongo_mapper/plugins/querying/plucky_methods.rb +15 -0
  78. data/lib/mongo_mapper/plugins/rails.rb +58 -0
  79. data/lib/mongo_mapper/plugins/safe.rb +28 -0
  80. data/lib/mongo_mapper/plugins/sci.rb +32 -0
  81. data/lib/mongo_mapper/plugins/scopes.rb +21 -0
  82. data/lib/mongo_mapper/plugins/serialization.rb +76 -0
  83. data/lib/mongo_mapper/plugins/timestamps.rb +22 -0
  84. data/lib/mongo_mapper/plugins/userstamps.rb +15 -0
  85. data/lib/mongo_mapper/plugins/validations.rb +50 -0
  86. data/lib/mongo_mapper/support/descendant_appends.rb +45 -0
  87. data/lib/mongo_mapper/version.rb +4 -0
  88. data/rails/init.rb +19 -0
  89. data/test/_NOTE_ON_TESTING +1 -0
  90. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  91. data/test/functional/associations/test_belongs_to_proxy.rb +93 -0
  92. data/test/functional/associations/test_in_array_proxy.rb +319 -0
  93. data/test/functional/associations/test_many_documents_as_proxy.rb +229 -0
  94. data/test/functional/associations/test_many_documents_proxy.rb +615 -0
  95. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +176 -0
  96. data/test/functional/associations/test_many_embedded_proxy.rb +256 -0
  97. data/test/functional/associations/test_many_polymorphic_proxy.rb +302 -0
  98. data/test/functional/associations/test_one_embedded_proxy.rb +81 -0
  99. data/test/functional/associations/test_one_proxy.rb +181 -0
  100. data/test/functional/test_accessible.rb +168 -0
  101. data/test/functional/test_associations.rb +44 -0
  102. data/test/functional/test_binary.rb +27 -0
  103. data/test/functional/test_caching.rb +76 -0
  104. data/test/functional/test_callbacks.rb +151 -0
  105. data/test/functional/test_dirty.rb +163 -0
  106. data/test/functional/test_document.rb +253 -0
  107. data/test/functional/test_dynamic_querying.rb +75 -0
  108. data/test/functional/test_embedded_document.rb +210 -0
  109. data/test/functional/test_identity_map.rb +514 -0
  110. data/test/functional/test_indexes.rb +42 -0
  111. data/test/functional/test_logger.rb +20 -0
  112. data/test/functional/test_modifiers.rb +416 -0
  113. data/test/functional/test_pagination.rb +91 -0
  114. data/test/functional/test_protected.rb +175 -0
  115. data/test/functional/test_querying.rb +873 -0
  116. data/test/functional/test_safe.rb +76 -0
  117. data/test/functional/test_sci.rb +230 -0
  118. data/test/functional/test_scopes.rb +171 -0
  119. data/test/functional/test_string_id_compatibility.rb +67 -0
  120. data/test/functional/test_timestamps.rb +62 -0
  121. data/test/functional/test_userstamps.rb +27 -0
  122. data/test/functional/test_validations.rb +342 -0
  123. data/test/models.rb +233 -0
  124. data/test/test_active_model_lint.rb +13 -0
  125. data/test/test_helper.rb +100 -0
  126. data/test/unit/associations/test_base.rb +212 -0
  127. data/test/unit/associations/test_proxy.rb +105 -0
  128. data/test/unit/serializers/test_json_serializer.rb +217 -0
  129. data/test/unit/test_clone.rb +69 -0
  130. data/test/unit/test_descendant_appends.rb +71 -0
  131. data/test/unit/test_document.rb +213 -0
  132. data/test/unit/test_dynamic_finder.rb +125 -0
  133. data/test/unit/test_embedded_document.rb +644 -0
  134. data/test/unit/test_extensions.rb +376 -0
  135. data/test/unit/test_key.rb +185 -0
  136. data/test/unit/test_keys.rb +89 -0
  137. data/test/unit/test_mongo_mapper.rb +110 -0
  138. data/test/unit/test_pagination.rb +11 -0
  139. data/test/unit/test_plugins.rb +50 -0
  140. data/test/unit/test_rails.rb +181 -0
  141. data/test/unit/test_rails_compatibility.rb +52 -0
  142. data/test/unit/test_serialization.rb +51 -0
  143. data/test/unit/test_time_zones.rb +39 -0
  144. data/test/unit/test_validations.rb +564 -0
  145. metadata +337 -0
@@ -0,0 +1,29 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class BelongsToPolymorphicProxy < Proxy
6
+ def replace(doc)
7
+ if doc
8
+ doc.save if doc.new?
9
+ id, type = doc.id, doc.class.name
10
+ end
11
+
12
+ proxy_owner[association.foreign_key] = id
13
+ proxy_owner[association.type_key_name] = type
14
+ reset
15
+ end
16
+
17
+ protected
18
+ def find_target
19
+ return nil if association_class.nil? || proxy_owner[association.foreign_key].nil?
20
+ association_class.find_by_id(proxy_owner[association.foreign_key])
21
+ end
22
+
23
+ def association_class
24
+ proxy_owner[association.type_key_name] ? proxy_owner[association.type_key_name].constantize : nil
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class BelongsToProxy < Proxy
6
+ def replace(doc)
7
+ if doc
8
+ doc.save if doc.new?
9
+ id = doc.id
10
+ end
11
+
12
+ proxy_owner[association.foreign_key] = id
13
+ reload
14
+ end
15
+
16
+ protected
17
+ def find_target
18
+ return nil if proxy_owner[association.foreign_key].nil?
19
+ klass.find_by_id(proxy_owner[association.foreign_key])
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class Collection < Proxy
6
+ def to_ary
7
+ load_target
8
+ if target.is_a?(Array)
9
+ target.to_ary
10
+ else
11
+ Array(target)
12
+ end
13
+ end
14
+
15
+ def include?(*args)
16
+ load_target
17
+ target.include?(*args)
18
+ end
19
+
20
+ def reset
21
+ super
22
+ target = []
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class EmbeddedCollection < Collection
6
+ def build(attributes={})
7
+ doc = klass.new(attributes)
8
+ assign_references(doc)
9
+ self << doc
10
+ doc
11
+ end
12
+
13
+ def find(id)
14
+ load_target
15
+ target.detect { |item| item.id.to_s == id || item.id == id }
16
+ end
17
+
18
+ def count
19
+ load_target
20
+ target.size
21
+ end
22
+
23
+ def <<(*docs)
24
+ load_target
25
+ docs.each do |doc|
26
+ assign_references(doc)
27
+ target << doc
28
+ end
29
+ end
30
+ alias_method :push, :<<
31
+ alias_method :concat, :<<
32
+
33
+ private
34
+ def assign_references(*docs)
35
+ docs.each { |doc| doc._parent_document = proxy_owner }
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,127 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class InArrayProxy < Collection
6
+ include DynamicQuerying::ClassMethods
7
+
8
+ def find(*args)
9
+ query.find(*scoped_ids(args))
10
+ end
11
+
12
+ def find!(*args)
13
+ query.find!(*scoped_ids(args))
14
+ end
15
+
16
+ def paginate(options)
17
+ query.paginate(options)
18
+ end
19
+
20
+ def all(options={})
21
+ query(options).all
22
+ end
23
+
24
+ def first(options={})
25
+ query(options).first
26
+ end
27
+
28
+ def last(options={})
29
+ query(options).last
30
+ end
31
+
32
+ def count(options={})
33
+ options.blank? ? ids.size : query(options).count
34
+ end
35
+
36
+ def destroy_all(options={})
37
+ all(options).each do |doc|
38
+ ids.delete(doc.id)
39
+ doc.destroy
40
+ end
41
+ reset
42
+ end
43
+
44
+ def delete_all(options={})
45
+ docs = query(options).fields(:_id).all
46
+ docs.each { |doc| ids.delete(doc.id) }
47
+ klass.delete(docs.map(&:id))
48
+ reset
49
+ end
50
+
51
+ def nullify
52
+ replace([])
53
+ reset
54
+ end
55
+
56
+ def create(attrs={})
57
+ doc = klass.create(attrs)
58
+ unless doc.new?
59
+ ids << doc.id
60
+ proxy_owner.save
61
+ reset
62
+ end
63
+ doc
64
+ end
65
+
66
+ def create!(attrs={})
67
+ doc = klass.create!(attrs)
68
+ unless doc.new?
69
+ ids << doc.id
70
+ proxy_owner.save
71
+ reset
72
+ end
73
+ doc
74
+ end
75
+
76
+ def <<(*docs)
77
+ flatten_deeper(docs).each do |doc|
78
+ doc.save if doc.new?
79
+ unless ids.include?(doc.id)
80
+ ids << doc.id
81
+ end
82
+ end
83
+ reset
84
+ end
85
+ alias_method :push, :<<
86
+ alias_method :concat, :<<
87
+
88
+ def replace(docs)
89
+ doc_ids = docs.map do |doc|
90
+ doc.save if doc.new?
91
+ doc.id
92
+ end
93
+ ids.replace(doc_ids.uniq)
94
+ reset
95
+ end
96
+
97
+ private
98
+ def query(options={})
99
+ klass.
100
+ query(association.query_options).
101
+ update(options).
102
+ update(criteria)
103
+ end
104
+
105
+ def criteria
106
+ {:_id => ids}
107
+ end
108
+
109
+ def scoped_ids(args)
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
115
+ end
116
+
117
+ def find_target
118
+ ids.blank? ? [] : all
119
+ end
120
+
121
+ def ids
122
+ proxy_owner[options[:in]]
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,28 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class ManyDocumentsAsProxy < ManyDocumentsProxy
6
+ protected
7
+ def criteria
8
+ {type_key_name => proxy_owner.class.name, id_key_name => proxy_owner.id}
9
+ end
10
+
11
+ def apply_scope(doc)
12
+ ensure_owner_saved
13
+ criteria.each { |key, value| doc[key] = value }
14
+ doc
15
+ end
16
+
17
+ private
18
+ def type_key_name
19
+ "#{options[:as]}_type"
20
+ end
21
+
22
+ def id_key_name
23
+ "#{options[:as]}_id"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,109 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class ManyDocumentsProxy < Collection
6
+ include DynamicQuerying::ClassMethods
7
+ include Querying::PluckyMethods
8
+
9
+ def replace(docs)
10
+ load_target
11
+ target.map(&:destroy)
12
+ docs.each { |doc| prepare(doc).save }
13
+ reset
14
+ end
15
+
16
+ def <<(*docs)
17
+ ensure_owner_saved
18
+ flatten_deeper(docs).each { |doc| prepare(doc).save }
19
+ reset
20
+ end
21
+ alias_method :push, :<<
22
+ alias_method :concat, :<<
23
+
24
+ def build(attrs={})
25
+ doc = klass.new(attrs)
26
+ apply_scope(doc)
27
+ @target ||= [] unless loaded?
28
+ @target << doc
29
+ doc
30
+ end
31
+
32
+ def create(attrs={})
33
+ doc = klass.new(attrs)
34
+ apply_scope(doc).save
35
+ reset
36
+ doc
37
+ end
38
+
39
+ def create!(attrs={})
40
+ doc = klass.new(attrs)
41
+ apply_scope(doc).save!
42
+ reset
43
+ doc
44
+ end
45
+
46
+ def destroy_all(options={})
47
+ all(options).map(&:destroy)
48
+ reset
49
+ end
50
+
51
+ def delete_all(options={})
52
+ query(options).remove
53
+ reset
54
+ end
55
+
56
+ def nullify
57
+ all.each { |doc| doc.update_attributes(self.foreign_key => nil) }
58
+ reset
59
+ end
60
+
61
+ def save_to_collection(options={})
62
+ @target.each { |doc| doc.save(options) } if @target
63
+ end
64
+
65
+ protected
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
80
+ end
81
+
82
+ def criteria
83
+ {self.foreign_key => proxy_owner.id}
84
+ end
85
+
86
+ def find_target
87
+ all
88
+ end
89
+
90
+ def ensure_owner_saved
91
+ proxy_owner.save if proxy_owner.new?
92
+ end
93
+
94
+ def prepare(doc)
95
+ klass === doc ? apply_scope(doc) : build(doc)
96
+ end
97
+
98
+ def apply_scope(doc)
99
+ criteria.each { |key, value| doc[key] = value }
100
+ doc
101
+ end
102
+
103
+ def foreign_key
104
+ options[:foreign_key] || proxy_owner.class.name.to_s.underscore.gsub("/", "_") + "_id"
105
+ end
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class ManyEmbeddedPolymorphicProxy < EmbeddedCollection
6
+ def replace(values)
7
+ @_values = values.map do |v|
8
+ v.respond_to?(:attributes) ? v.attributes.merge(association.type_key_name => v.class.name) : v
9
+ end
10
+ reset
11
+ end
12
+
13
+ protected
14
+ def find_target
15
+ (@_values || []).map do |hash|
16
+ child = polymorphic_class(hash).load(hash)
17
+ assign_references(child)
18
+ child
19
+ end
20
+ end
21
+
22
+ def polymorphic_class(doc)
23
+ if class_name = doc[association.type_key_name]
24
+ class_name.constantize
25
+ else
26
+ klass
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Associations
5
+ class ManyEmbeddedProxy < EmbeddedCollection
6
+ def replace(values)
7
+ @_values = values.map do |v|
8
+ v.respond_to?(:attributes) ? v.attributes : v
9
+ end
10
+ reset
11
+ end
12
+
13
+ private
14
+ def find_target
15
+ (@_values || []).map do |attrs|
16
+ klass.load(attrs).tap do |child|
17
+ assign_references(child)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end