mongo_mapper 0.6.10 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
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