ign-mongo_mapper 0.8.6.1

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 (147) 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/keys.rb +40 -0
  12. data/examples/modifiers/set.rb +25 -0
  13. data/examples/plugins.rb +41 -0
  14. data/examples/querying.rb +35 -0
  15. data/examples/safe.rb +43 -0
  16. data/examples/scopes.rb +52 -0
  17. data/examples/validating/embedded_docs.rb +29 -0
  18. data/lib/mongo_mapper.rb +83 -0
  19. data/lib/mongo_mapper/connection.rb +83 -0
  20. data/lib/mongo_mapper/document.rb +41 -0
  21. data/lib/mongo_mapper/embedded_document.rb +31 -0
  22. data/lib/mongo_mapper/exceptions.rb +27 -0
  23. data/lib/mongo_mapper/extensions/array.rb +19 -0
  24. data/lib/mongo_mapper/extensions/binary.rb +22 -0
  25. data/lib/mongo_mapper/extensions/boolean.rb +44 -0
  26. data/lib/mongo_mapper/extensions/date.rb +25 -0
  27. data/lib/mongo_mapper/extensions/float.rb +14 -0
  28. data/lib/mongo_mapper/extensions/hash.rb +14 -0
  29. data/lib/mongo_mapper/extensions/integer.rb +19 -0
  30. data/lib/mongo_mapper/extensions/kernel.rb +9 -0
  31. data/lib/mongo_mapper/extensions/nil_class.rb +18 -0
  32. data/lib/mongo_mapper/extensions/object.rb +27 -0
  33. data/lib/mongo_mapper/extensions/object_id.rb +30 -0
  34. data/lib/mongo_mapper/extensions/set.rb +20 -0
  35. data/lib/mongo_mapper/extensions/string.rb +18 -0
  36. data/lib/mongo_mapper/extensions/time.rb +29 -0
  37. data/lib/mongo_mapper/middleware/identity_map.rb +16 -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 +134 -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 +151 -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 +41 -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 +243 -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 +311 -0
  69. data/lib/mongo_mapper/plugins/keys/key.rb +65 -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 +15 -0
  89. data/test/_NOTE_ON_TESTING +1 -0
  90. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +64 -0
  91. data/test/functional/associations/test_belongs_to_proxy.rb +117 -0
  92. data/test/functional/associations/test_in_array_proxy.rb +349 -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 +303 -0
  98. data/test/functional/associations/test_one_embedded_proxy.rb +100 -0
  99. data/test/functional/associations/test_one_proxy.rb +206 -0
  100. data/test/functional/test_accessible.rb +168 -0
  101. data/test/functional/test_associations.rb +46 -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 +272 -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 +513 -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 +102 -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 +208 -0
  132. data/test/unit/test_dynamic_finder.rb +125 -0
  133. data/test/unit/test_embedded_document.rb +639 -0
  134. data/test/unit/test_extensions.rb +376 -0
  135. data/test/unit/test_identity_map_middleware.rb +34 -0
  136. data/test/unit/test_inspect.rb +22 -0
  137. data/test/unit/test_key.rb +205 -0
  138. data/test/unit/test_keys.rb +89 -0
  139. data/test/unit/test_mongo_mapper.rb +110 -0
  140. data/test/unit/test_pagination.rb +11 -0
  141. data/test/unit/test_plugins.rb +50 -0
  142. data/test/unit/test_rails.rb +181 -0
  143. data/test/unit/test_rails_compatibility.rb +52 -0
  144. data/test/unit/test_serialization.rb +51 -0
  145. data/test/unit/test_time_zones.rb +39 -0
  146. data/test/unit/test_validations.rb +564 -0
  147. metadata +385 -0
@@ -0,0 +1,32 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Sci
5
+ module ClassMethods
6
+ def inherited(subclass)
7
+ key :_type, String unless key?(:_type)
8
+ subclass.instance_variable_set("@single_collection_inherited", true)
9
+ subclass.set_collection_name(collection_name) unless subclass.embeddable?
10
+ super
11
+ end
12
+
13
+ def single_collection_inherited?
14
+ @single_collection_inherited == true
15
+ end
16
+
17
+ def query(options={})
18
+ super.tap do |query|
19
+ query[:_type] = name if single_collection_inherited?
20
+ end
21
+ end
22
+ end
23
+
24
+ module InstanceMethods
25
+ def initialize(*args)
26
+ super
27
+ write_key :_type, self.class.name if self.class.key?(:_type)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,21 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Scopes
5
+ module ClassMethods
6
+ def scope(name, scope_options={})
7
+ scopes[name] = lambda do |*args|
8
+ result = scope_options.is_a?(Proc) ? scope_options.call(*args) : scope_options
9
+ result = self.query(result) if result.is_a?(Hash)
10
+ self.query.merge(result)
11
+ end
12
+ singleton_class.send :define_method, name, &scopes[name]
13
+ end
14
+
15
+ def scopes
16
+ read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: UTF-8
2
+ require 'active_support/json'
3
+
4
+ module MongoMapper
5
+ module Plugins
6
+ module Serialization
7
+ def self.configure(model)
8
+ model.class_eval { cattr_accessor :include_root_in_json, :instance_writer => true }
9
+ end
10
+
11
+ module InstanceMethods
12
+ def as_json options={}
13
+ options ||= {}
14
+ unless options[:only]
15
+ methods = [options.delete(:methods)].flatten.compact
16
+ methods << :id
17
+ options[:methods] = methods.uniq
18
+ end
19
+
20
+ except = [options.delete(:except)].flatten.compact
21
+ except << :_id
22
+ options[:except] = except
23
+
24
+ # Direct rip from Rails 3 ActiveModel Serialization (#serializable_hash)
25
+ hash = begin
26
+ options[:only] = Array.wrap(options[:only]).map { |n| n.to_s }
27
+ options[:except] = Array.wrap(options[:except]).map { |n| n.to_s }
28
+
29
+ attribute_names = attributes.keys.sort
30
+ if options[:only].any?
31
+ attribute_names &= options[:only]
32
+ elsif options[:except].any?
33
+ attribute_names -= options[:except]
34
+ end
35
+
36
+ method_names = Array.wrap(options[:methods]).inject([]) do |methods, name|
37
+ methods << name if respond_to?(name.to_s)
38
+ methods
39
+ end
40
+
41
+ (attribute_names + method_names).inject({}) { |hash, name|
42
+ hash[name] = send(name)
43
+ hash
44
+ }
45
+ end
46
+ # End rip
47
+
48
+ options.delete(:only) if options[:only].nil? or options[:only].empty?
49
+
50
+ hash.each do |key, value|
51
+ if value.is_a?(Array)
52
+ hash[key] = value.map do |item|
53
+ item.respond_to?(:as_json) ? item.as_json(options) : item
54
+ end
55
+ elsif value.is_a? BSON::ObjectId
56
+ hash[key] = value.to_s
57
+ elsif value.respond_to?(:as_json)
58
+ hash[key] = value.as_json(options)
59
+ end
60
+ end
61
+
62
+ # Replicate Rails 3 naming - and also bin anytihng after : for use in our dynamic classes from unit tests
63
+ hash = { ActiveSupport::Inflector.underscore(ActiveSupport::Inflector.demodulize(self.class.name)).gsub(/:.*/,'') => hash } if include_root_in_json
64
+ hash
65
+ end
66
+ end
67
+
68
+ module ClassMethods
69
+ def from_json(json)
70
+ self.new(ActiveSupport::JSON.decode(json))
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Timestamps
5
+ module ClassMethods
6
+ def timestamps!
7
+ key :created_at, Time
8
+ key :updated_at, Time
9
+ class_eval { before_save :update_timestamps }
10
+ end
11
+ end
12
+
13
+ module InstanceMethods
14
+ def update_timestamps
15
+ now = Time.now.utc
16
+ self[:created_at] = now if new? && !created_at?
17
+ self[:updated_at] = now
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Userstamps
5
+ module ClassMethods
6
+ def userstamps!
7
+ key :creator_id, ObjectId
8
+ key :updater_id, ObjectId
9
+ belongs_to :creator, :class_name => 'User'
10
+ belongs_to :updater, :class_name => 'User'
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module Validations
5
+ def self.configure(model)
6
+ model.class_eval do
7
+ include Validatable
8
+ extend Validations::DocumentMacros
9
+ end
10
+ end
11
+
12
+ module DocumentMacros
13
+ def validates_uniqueness_of(*args)
14
+ add_validations(args, Validations::ValidatesUniquenessOf)
15
+ end
16
+ end
17
+
18
+ class ValidatesUniquenessOf < Validatable::ValidationBase
19
+ option :scope, :case_sensitive
20
+ default :case_sensitive => true
21
+
22
+ def valid?(instance)
23
+ value = instance[attribute]
24
+ return allow_nil if value.nil? and not allow_nil.nil?
25
+ return allow_blank if value.blank? and not allow_blank.nil?
26
+ base_conditions = case_sensitive ? {self.attribute => value} : {}
27
+ doc = instance.class.first(base_conditions.merge(scope_conditions(instance)).merge(where_conditions(instance)))
28
+ doc.nil? || instance._id == doc._id
29
+ end
30
+
31
+ def message(instance)
32
+ super || "has already been taken"
33
+ end
34
+
35
+ def scope_conditions(instance)
36
+ return {} unless scope
37
+ Array(scope).inject({}) do |conditions, key|
38
+ conditions.merge(key => instance[key])
39
+ end
40
+ end
41
+
42
+ def where_conditions(instance)
43
+ conditions = {}
44
+ conditions[attribute] = /^#{Regexp.escape(instance[attribute].to_s)}$/i unless case_sensitive
45
+ conditions
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+ require 'set'
3
+
4
+ module MongoMapper
5
+ module Support
6
+ module DescendantAppends
7
+ def included(model)
8
+ extra_extensions.each { |extension| model.extend(extension) }
9
+ extra_inclusions.each { |inclusion| model.send(:include, inclusion) }
10
+ descendants << model
11
+ end
12
+
13
+ # @api public
14
+ def descendants
15
+ @descendants ||= Set.new
16
+ end
17
+
18
+ # @api public
19
+ def append_extensions(*extensions)
20
+ extra_extensions.concat(extensions)
21
+ descendants.each do |model|
22
+ extensions.each { |extension| model.extend(extension) }
23
+ end
24
+ end
25
+
26
+ # @api public
27
+ def append_inclusions(*inclusions)
28
+ extra_inclusions.concat(inclusions)
29
+ descendants.each do |model|
30
+ inclusions.each { |inclusion| model.send(:include, inclusion) }
31
+ end
32
+ end
33
+
34
+ # @api private
35
+ def extra_extensions
36
+ @extra_extensions ||= []
37
+ end
38
+
39
+ # @api private
40
+ def extra_inclusions
41
+ @extra_inclusions ||= []
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ Version = '0.8.6.1'
4
+ end
data/rails/init.rb ADDED
@@ -0,0 +1,15 @@
1
+ # See http://groups.google.com/group/mongomapper/browse_thread/thread/68f62e8eda43b43a/4841dba76938290c
2
+ #
3
+ # to_prepare is called before each request in development mode and the first request in production.
4
+ Rails.configuration.to_prepare do
5
+ if !Rails.configuration.cache_classes
6
+ # Rails reloading was making descendants fill up and leak memory, these make sure they get cleared
7
+ MongoMapper::Document.descendants.each {|m| m.descendants.clear if m.respond_to?(:descendants) }
8
+ MongoMapper::Document.descendants.clear
9
+ MongoMapper::EmbeddedDocument.descendants.each {|m| m.descendants.clear if m.respond_to?(:descendants) }
10
+ MongoMapper::EmbeddedDocument.descendants.clear
11
+ MongoMapper::Plugins::IdentityMap.models.clear
12
+ end
13
+ end
14
+
15
+ config.middleware.use 'MongoMapper::Middleware::IdentityMap'
@@ -0,0 +1 @@
1
+ I am doing my best to keep unit and functional tests separate. As I see them, functional tests hit the database and should never care about internals. Unit tests do not hit the database.
@@ -0,0 +1,64 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToPolymorphicProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ Status.collection.remove
7
+ Project.collection.remove
8
+ end
9
+
10
+ should "default to nil" do
11
+ status = Status.new
12
+ status.target.nil?.should be_true
13
+ status.target.inspect.should == "nil"
14
+ end
15
+
16
+ should "have boolean presence method" do
17
+ status = Status.new
18
+ status.target?.should be_false
19
+
20
+ status.target = Project.new(:name => 'mongomapper')
21
+ status.target?.should be_true
22
+ end
23
+
24
+ should "be able to replace the association" do
25
+ status = Status.new(:name => 'Foo!')
26
+ project = Project.new(:name => "mongomapper")
27
+ status.target = project
28
+ status.save.should be_true
29
+
30
+ status = status.reload
31
+ status.target.nil?.should be_false
32
+ status.target_id.should == project._id
33
+ status.target_type.should == "Project"
34
+ status.target.name.should == "mongomapper"
35
+ end
36
+
37
+ should "unset the association" do
38
+ status = Status.new(:name => 'Foo!')
39
+ project = Project.new(:name => "mongomapper")
40
+ status.target = project
41
+ status.save.should be_true
42
+
43
+ status = status.reload
44
+ status.target = nil
45
+ status.target_type.nil?.should be_true
46
+ status.target_id.nil?.should be_true
47
+ status.target.nil?.should be_true
48
+ end
49
+
50
+ context "association id set but document not found" do
51
+ setup do
52
+ @status = Status.new(:name => 'Foo!')
53
+ project = Project.new(:name => "mongomapper")
54
+ @status.target = project
55
+ @status.save.should be_true
56
+ project.destroy
57
+ @status.reload
58
+ end
59
+
60
+ should "return nil instead of raising error" do
61
+ @status.target.nil?.should be_true
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,117 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class BelongsToProxyTest < Test::Unit::TestCase
5
+ def setup
6
+ @post_class = Doc()
7
+ @comment_class = Doc do
8
+ key :post_id, String
9
+ end
10
+
11
+ @comment_class.belongs_to :post, :class => @post_class
12
+ end
13
+
14
+ should "default to nil" do
15
+ @comment_class.new.post.nil?.should be_true
16
+ end
17
+
18
+ should "return nil instead of a proxy" do
19
+ nil.should === @comment_class.new.post
20
+ end
21
+
22
+ should "have boolean presence method" do
23
+ comment = @comment_class.new(:name => 'Foo!')
24
+ comment.post?.should be_false
25
+
26
+ comment.post = @post_class.new(:name => 'mongomapper')
27
+ comment.post?.should be_true
28
+ end
29
+
30
+ should "be able to replace the association" do
31
+ post = @post_class.new(:name => 'mongomapper')
32
+ comment = @comment_class.new(:name => 'Foo!', :post => post)
33
+ comment.save.should be_true
34
+
35
+ comment = comment.reload
36
+ comment.post.should == post
37
+ comment.post.nil?.should be_false
38
+ end
39
+
40
+ should "generate a new proxy when replacing the association" do
41
+ post1 = @post_class.create(:name => 'post1')
42
+ post2 = @post_class.create(:name => 'post2')
43
+
44
+ comment = @comment_class.new(:name => 'Foo!', :post => post1)
45
+ comment.save.should be_true
46
+
47
+
48
+ comment = comment.reload
49
+ comment.post.should == post1
50
+ comment.post.nil?.should be_false
51
+
52
+ original_post = comment.post
53
+ original_post.name.should == 'post1'
54
+
55
+ comment.post = post2
56
+ comment.post.name.should == 'post2'
57
+ original_post.name.should == 'post1'
58
+ end
59
+
60
+ should "unset the association" do
61
+ post = @post_class.new(:name => 'mongomapper')
62
+ comment = @comment_class.new(:name => 'Foo!', :post => post)
63
+ comment.save.should be_true
64
+
65
+ comment = comment.reload
66
+ comment.post = nil
67
+ comment.post.nil?.should be_true
68
+ end
69
+
70
+ should "return nil if id set but document not found" do
71
+ id = BSON::ObjectId.new
72
+ @comment_class.new(:name => 'Foo', :post_id => id).post.nil?.should be_true
73
+ end
74
+
75
+ context ":dependent" do
76
+ setup do
77
+ # FIXME: make use of already defined models
78
+ class ::Property
79
+ include MongoMapper::Document
80
+ end
81
+ Property.collection.remove
82
+
83
+ class ::Thing
84
+ include MongoMapper::Document
85
+ key :name, String
86
+ end
87
+ Thing.collection.remove
88
+ end
89
+
90
+ teardown do
91
+ Object.send :remove_const, 'Property' if defined?(::Property)
92
+ Object.send :remove_const, 'Thing' if defined?(::Thing)
93
+ end
94
+
95
+ context "=> destroy" do
96
+ setup do
97
+ Property.key :thing_id, ObjectId
98
+ Property.belongs_to :thing, :dependent => :destroy
99
+ Thing.many :properties
100
+
101
+ @thing = Thing.create(:name => "Tree")
102
+ @property1 = Property.create
103
+ @property2 = Property.create
104
+ @property3 = Property.create
105
+ @thing.properties << @property1
106
+ @thing.properties << @property2
107
+ @thing.properties << @property3
108
+ end
109
+
110
+ should "not execute on a belongs_to association" do
111
+ Thing.count.should == 1
112
+ @property1.destroy
113
+ Thing.count.should == 1
114
+ end
115
+ end
116
+ end
117
+ end