mongo_mapper 0.6.10 → 0.7.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.
Files changed (106) hide show
  1. data/README.rdoc +5 -14
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/lib/mongo_mapper.rb +48 -56
  5. data/lib/mongo_mapper/document.rb +136 -164
  6. data/lib/mongo_mapper/embedded_document.rb +29 -354
  7. data/lib/mongo_mapper/plugins.rb +31 -0
  8. data/lib/mongo_mapper/plugins/associations.rb +105 -0
  9. data/lib/mongo_mapper/plugins/associations/base.rb +123 -0
  10. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +30 -0
  11. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +25 -0
  12. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  13. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +50 -0
  14. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  15. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  16. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  17. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  18. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  19. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  20. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +68 -0
  21. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  22. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  23. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  24. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  25. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  26. data/lib/mongo_mapper/plugins/equality.rb +23 -0
  27. data/lib/mongo_mapper/plugins/identity_map.rb +122 -0
  28. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  29. data/lib/mongo_mapper/plugins/keys.rb +324 -0
  30. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  31. data/lib/mongo_mapper/plugins/pagination.rb +24 -0
  32. data/lib/mongo_mapper/plugins/pagination/proxy.rb +68 -0
  33. data/lib/mongo_mapper/plugins/protected.rb +45 -0
  34. data/lib/mongo_mapper/plugins/rails.rb +45 -0
  35. data/lib/mongo_mapper/plugins/serialization.rb +105 -0
  36. data/lib/mongo_mapper/plugins/validations.rb +46 -0
  37. data/lib/mongo_mapper/query.rb +130 -0
  38. data/lib/mongo_mapper/support.rb +40 -17
  39. data/lib/mongo_mapper/support/descendant_appends.rb +46 -0
  40. data/lib/mongo_mapper/support/find.rb +77 -0
  41. data/mongo_mapper.gemspec +55 -38
  42. data/performance/read_write.rb +52 -0
  43. data/specs.watchr +23 -2
  44. data/test/functional/associations/test_belongs_to_proxy.rb +12 -10
  45. data/test/functional/associations/test_many_documents_as_proxy.rb +4 -21
  46. data/test/functional/associations/test_many_documents_proxy.rb +2 -8
  47. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +59 -39
  48. data/test/functional/associations/test_many_embedded_proxy.rb +145 -81
  49. data/test/functional/associations/test_many_polymorphic_proxy.rb +2 -40
  50. data/test/functional/associations/test_one_proxy.rb +25 -10
  51. data/test/functional/test_binary.rb +2 -8
  52. data/test/functional/test_callbacks.rb +1 -5
  53. data/test/functional/test_dirty.rb +27 -23
  54. data/test/functional/test_document.rb +224 -165
  55. data/test/functional/test_embedded_document.rb +72 -82
  56. data/test/functional/test_identity_map.rb +508 -0
  57. data/test/functional/test_modifiers.rb +15 -5
  58. data/test/functional/test_pagination.rb +1 -3
  59. data/test/functional/test_protected.rb +155 -0
  60. data/test/functional/test_string_id_compatibility.rb +7 -12
  61. data/test/functional/test_validations.rb +26 -58
  62. data/test/models.rb +0 -39
  63. data/test/test_helper.rb +37 -3
  64. data/test/unit/associations/test_base.rb +5 -5
  65. data/test/unit/associations/test_proxy.rb +8 -6
  66. data/test/unit/test_descendant_appends.rb +71 -0
  67. data/test/unit/test_document.rb +71 -76
  68. data/test/unit/test_dynamic_finder.rb +27 -29
  69. data/test/unit/test_embedded_document.rb +555 -601
  70. data/test/unit/{test_key.rb → test_keys.rb} +2 -5
  71. data/test/unit/test_mongo_mapper.rb +69 -9
  72. data/test/unit/test_pagination.rb +40 -32
  73. data/test/unit/test_plugins.rb +50 -0
  74. data/test/unit/{test_finder_options.rb → test_query.rb} +74 -65
  75. data/test/unit/test_rails.rb +123 -0
  76. data/test/unit/{test_serializations.rb → test_serialization.rb} +1 -2
  77. data/test/unit/test_support.rb +23 -7
  78. data/test/unit/test_time_zones.rb +3 -4
  79. data/test/unit/test_validations.rb +58 -17
  80. metadata +53 -36
  81. data/lib/mongo_mapper/associations.rb +0 -78
  82. data/lib/mongo_mapper/associations/base.rb +0 -119
  83. data/lib/mongo_mapper/associations/belongs_to_polymorphic_proxy.rb +0 -26
  84. data/lib/mongo_mapper/associations/belongs_to_proxy.rb +0 -21
  85. data/lib/mongo_mapper/associations/collection.rb +0 -19
  86. data/lib/mongo_mapper/associations/in_array_proxy.rb +0 -137
  87. data/lib/mongo_mapper/associations/many_documents_as_proxy.rb +0 -26
  88. data/lib/mongo_mapper/associations/many_documents_proxy.rb +0 -115
  89. data/lib/mongo_mapper/associations/many_embedded_polymorphic_proxy.rb +0 -31
  90. data/lib/mongo_mapper/associations/many_embedded_proxy.rb +0 -54
  91. data/lib/mongo_mapper/associations/many_polymorphic_proxy.rb +0 -11
  92. data/lib/mongo_mapper/associations/one_proxy.rb +0 -64
  93. data/lib/mongo_mapper/associations/proxy.rb +0 -116
  94. data/lib/mongo_mapper/callbacks.rb +0 -61
  95. data/lib/mongo_mapper/dirty.rb +0 -117
  96. data/lib/mongo_mapper/dynamic_finder.rb +0 -74
  97. data/lib/mongo_mapper/finder_options.rb +0 -145
  98. data/lib/mongo_mapper/key.rb +0 -36
  99. data/lib/mongo_mapper/mongo_mapper.rb +0 -125
  100. data/lib/mongo_mapper/pagination.rb +0 -66
  101. data/lib/mongo_mapper/rails_compatibility/document.rb +0 -15
  102. data/lib/mongo_mapper/rails_compatibility/embedded_document.rb +0 -28
  103. data/lib/mongo_mapper/serialization.rb +0 -54
  104. data/lib/mongo_mapper/serializers/json_serializer.rb +0 -48
  105. data/lib/mongo_mapper/validations.rb +0 -39
  106. data/test/functional/test_rails_compatibility.rb +0 -25
@@ -1,31 +0,0 @@
1
- module MongoMapper
2
- module Associations
3
- class ManyEmbeddedPolymorphicProxy < Collection
4
- def replace(values)
5
- @_values = values.map do |v|
6
- if v.kind_of?(EmbeddedDocument)
7
- v.attributes.merge(reflection.type_key_name => v.class.name)
8
- else
9
- v
10
- end
11
- end
12
- reset
13
- end
14
-
15
- protected
16
- def find_target
17
- (@_values || []).map do |hash|
18
- polymorphic_class(hash).new(hash)
19
- end
20
- end
21
-
22
- def polymorphic_class(doc)
23
- if class_name = doc[reflection.type_key_name]
24
- class_name.constantize
25
- else
26
- klass
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,54 +0,0 @@
1
- module MongoMapper
2
- module Associations
3
- class ManyEmbeddedProxy < Collection
4
- def replace(values)
5
- @_values = values.map do |v|
6
- v.kind_of?(EmbeddedDocument) ? v.attributes : v
7
- end
8
- reset
9
- end
10
-
11
- def build(attributes={})
12
- doc = klass.new(attributes)
13
- assign_root_document(doc)
14
- self << doc
15
- doc
16
- end
17
-
18
- # TODO: test that both string and oid version work
19
- def find(id)
20
- load_target
21
- target.detect { |item| item.id.to_s == id || item.id == id }
22
- end
23
-
24
- def <<(*docs)
25
- load_target
26
- docs.each do |doc|
27
- assign_root_document(doc)
28
- target << doc
29
- end
30
- end
31
- alias_method :push, :<<
32
- alias_method :concat, :<<
33
-
34
- private
35
- def find_target
36
- (@_values || []).map do |v|
37
- child = klass.new(v)
38
- assign_root_document(child)
39
- child
40
- end
41
- end
42
-
43
- def root_document
44
- owner._root_document || owner
45
- end
46
-
47
- def assign_root_document(*docs)
48
- docs.each do |doc|
49
- doc._root_document = root_document
50
- end
51
- end
52
- end
53
- end
54
- end
@@ -1,11 +0,0 @@
1
- module MongoMapper
2
- module Associations
3
- class ManyPolymorphicProxy < ManyDocumentsProxy
4
- private
5
- def apply_scope(doc)
6
- doc[reflection.type_key_name] = doc.class.name
7
- super
8
- end
9
- end
10
- end
11
- end
@@ -1,64 +0,0 @@
1
- module MongoMapper
2
- module Associations
3
- class OneProxy < Proxy
4
- def build(attrs={})
5
- instantiate_target(:new, attrs)
6
- end
7
-
8
- def create(attrs={})
9
- instantiate_target(:create, attrs)
10
- end
11
-
12
- def create!(attrs={})
13
- instantiate_target(:create!, attrs)
14
- end
15
-
16
- def replace(doc)
17
- load_target
18
-
19
- if !target.nil? && target != doc
20
- if options[:dependent] && !target.new?
21
- case options[:dependent]
22
- when :delete
23
- target.delete
24
- when :destroy
25
- target.destroy
26
- when :nullify
27
- target[foreign_key] = nil
28
- target.save
29
- end
30
- end
31
- end
32
-
33
- reset
34
-
35
- unless doc.nil?
36
- owner.save if owner.new?
37
- doc[foreign_key] = owner.id
38
- doc.save if doc.new?
39
- loaded
40
- @target = doc
41
- end
42
- end
43
-
44
- protected
45
- def find_target
46
- target_class.first(foreign_key => owner.id)
47
- end
48
-
49
- def instantiate_target(instantiator, attrs={})
50
- @target = target_class.send(instantiator, attrs.update(foreign_key => owner.id))
51
- loaded
52
- @target
53
- end
54
-
55
- def target_class
56
- @target_class ||= options[:class] || (options[:class_name] || association.name.to_s.camelize).constantize
57
- end
58
-
59
- def foreign_key
60
- options[:foreign_key] || owner.class.name.foreign_key
61
- end
62
- end
63
- end
64
- end
@@ -1,116 +0,0 @@
1
- module MongoMapper
2
- module Associations
3
- class Proxy
4
- alias :proxy_respond_to? :respond_to?
5
- alias :proxy_extend :extend
6
-
7
- instance_methods.each { |m| undef_method m unless m =~ /(^__|^nil\?$|^send$|proxy_|^object_id$)/ }
8
-
9
- attr_reader :owner, :reflection, :target
10
-
11
- alias :proxy_owner :owner
12
- alias :proxy_target :target
13
- alias :proxy_reflection :reflection
14
-
15
- delegate :klass, :to => :proxy_reflection
16
- delegate :options, :to => :proxy_reflection
17
- delegate :collection, :to => :klass
18
-
19
- def initialize(owner, reflection)
20
- @owner, @reflection, @loaded = owner, reflection, false
21
- Array(reflection.options[:extend]).each { |ext| proxy_extend(ext) }
22
- reset
23
- end
24
-
25
- def inspect
26
- load_target
27
- target.inspect
28
- end
29
-
30
- def loaded?
31
- @loaded
32
- end
33
-
34
- def loaded
35
- @loaded = true
36
- end
37
-
38
- def nil?
39
- load_target
40
- target.nil?
41
- end
42
-
43
- def blank?
44
- load_target
45
- target.blank?
46
- end
47
-
48
- def present?
49
- load_target
50
- target.present?
51
- end
52
-
53
- def reload
54
- reset
55
- load_target
56
- self unless target.nil?
57
- end
58
-
59
- def replace(v)
60
- raise NotImplementedError
61
- end
62
-
63
- def reset
64
- @loaded = false
65
- @target = nil
66
- end
67
-
68
- def respond_to?(*args)
69
- proxy_respond_to?(*args) || (load_target && target.respond_to?(*args))
70
- end
71
-
72
- def send(method, *args)
73
- if proxy_respond_to?(method)
74
- super
75
- else
76
- load_target
77
- target.send(method, *args)
78
- end
79
- end
80
-
81
- def ===(other)
82
- load_target
83
- other === target
84
- end
85
-
86
- protected
87
- def method_missing(method, *args, &block)
88
- if load_target
89
- if block_given?
90
- target.send(method, *args) { |*block_args| block.call(*block_args) }
91
- else
92
- target.send(method, *args)
93
- end
94
- end
95
- end
96
-
97
- def load_target
98
- @target = find_target unless loaded?
99
- loaded
100
- @target
101
- rescue MongoMapper::DocumentNotFound
102
- reset
103
- end
104
-
105
- def find_target
106
- raise NotImplementedError
107
- end
108
-
109
- def flatten_deeper(array)
110
- array.collect do |element|
111
- (element.respond_to?(:flatten) && !element.is_a?(Hash)) ? element.flatten : element
112
- end.flatten
113
- end
114
- end
115
- end
116
- end
@@ -1,61 +0,0 @@
1
- module MongoMapper
2
- module Callbacks
3
- def self.included(model)
4
- model.class_eval do
5
- include ActiveSupport::Callbacks
6
-
7
- define_callbacks(
8
- :before_save, :after_save,
9
- :before_create, :after_create,
10
- :before_update, :after_update,
11
- :before_validation, :after_validation,
12
- :before_validation_on_create, :after_validation_on_create,
13
- :before_validation_on_update, :after_validation_on_update,
14
- :before_destroy, :after_destroy
15
- )
16
- end
17
- end
18
-
19
- def valid?
20
- action = new? ? 'create' : 'update'
21
-
22
- run_callbacks(:before_validation)
23
- run_callbacks("before_validation_on_#{action}".to_sym)
24
- result = super
25
- run_callbacks("after_validation_on_#{action}".to_sym)
26
- run_callbacks(:after_validation)
27
-
28
- result
29
- end
30
-
31
- def destroy
32
- run_callbacks(:before_destroy)
33
- result = super
34
- run_callbacks(:after_destroy)
35
- result
36
- end
37
-
38
- private
39
- def create_or_update(*args)
40
- run_callbacks(:before_save)
41
- if result = super
42
- run_callbacks(:after_save)
43
- end
44
- result
45
- end
46
-
47
- def create(*args)
48
- run_callbacks(:before_create)
49
- result = super
50
- run_callbacks(:after_create)
51
- result
52
- end
53
-
54
- def update(*args)
55
- run_callbacks(:before_update)
56
- result = super
57
- run_callbacks(:after_update)
58
- result
59
- end
60
- end
61
- end
@@ -1,117 +0,0 @@
1
- module MongoMapper
2
- module Dirty
3
- DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']
4
-
5
- def method_missing(method, *args, &block)
6
- if method.to_s =~ /(_changed\?|_change|_will_change!|_was)$/
7
- method_suffix = $1
8
- key = method.to_s.gsub(method_suffix, '')
9
-
10
- if key_names.include?(key)
11
- case method_suffix
12
- when '_changed?'
13
- key_changed?(key)
14
- when '_change'
15
- key_change(key)
16
- when '_will_change!'
17
- key_will_change!(key)
18
- when '_was'
19
- key_was(key)
20
- end
21
- else
22
- super
23
- end
24
- else
25
- super
26
- end
27
- end
28
-
29
- def changed?
30
- !changed_keys.empty?
31
- end
32
-
33
- def changed
34
- changed_keys.keys
35
- end
36
-
37
- def changes
38
- changed.inject({}) { |h, attribute| h[attribute] = key_change(attribute); h }
39
- end
40
-
41
- def initialize(attrs={})
42
- super(attrs)
43
- changed_keys.clear unless new?
44
- end
45
-
46
- def save(*args)
47
- if status = super
48
- changed_keys.clear
49
- end
50
- status
51
- end
52
-
53
- def save!(*args)
54
- status = super
55
- changed_keys.clear
56
- status
57
- end
58
-
59
- def reload(*args)
60
- record = super
61
- changed_keys.clear
62
- record
63
- end
64
-
65
- private
66
- def clone_key_value(attribute_name)
67
- value = send(:read_attribute, attribute_name)
68
- value.duplicable? ? value.clone : value
69
- rescue TypeError, NoMethodError
70
- value
71
- end
72
-
73
- def changed_keys
74
- @changed_keys ||= {}
75
- end
76
-
77
- def key_changed?(attribute)
78
- changed_keys.include?(attribute)
79
- end
80
-
81
- def key_change(attribute)
82
- [changed_keys[attribute], __send__(attribute)] if key_changed?(attribute)
83
- end
84
-
85
- def key_was(attribute)
86
- key_changed?(attribute) ? changed_keys[attribute] : __send__(attribute)
87
- end
88
-
89
- def key_will_change!(attribute)
90
- changed_keys[attribute] = clone_key_value(attribute)
91
- end
92
-
93
- def write_attribute(attribute, value)
94
- attribute = attribute.to_s
95
-
96
- if changed_keys.include?(attribute)
97
- old = changed_keys[attribute]
98
- changed_keys.delete(attribute) unless value_changed?(attribute, old, value)
99
- else
100
- old = clone_key_value(attribute)
101
- changed_keys[attribute] = old if value_changed?(attribute, old, value)
102
- end
103
-
104
- super(attribute, value)
105
- end
106
-
107
- def value_changed?(key_name, old, value)
108
- key = _keys[key_name]
109
-
110
- if key.number? && value.blank?
111
- value = nil
112
- end
113
-
114
- old != value
115
- end
116
- end
117
- end