mongomodel 0.4.9 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.travis.yml +30 -0
  2. data/Gemfile +1 -1
  3. data/README.md +7 -1
  4. data/Rakefile +0 -2
  5. data/gemfiles/mongo_mapper.gemfile +6 -7
  6. data/gemfiles/mongoid.gemfile +6 -7
  7. data/gemfiles/rails-3.1.gemfile +5 -6
  8. data/gemfiles/rails-3.2.gemfile +5 -6
  9. data/gemfiles/rails-4-observers.gemfile +6 -8
  10. data/gemfiles/rails-4-protected-attributes.gemfile +6 -8
  11. data/gemfiles/rails-4.gemfile +5 -7
  12. data/lib/mongomodel.rb +1 -0
  13. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +6 -1
  14. data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +17 -0
  15. data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +1 -1
  16. data/lib/mongomodel/concerns/attributes.rb +5 -0
  17. data/lib/mongomodel/concerns/properties.rb +2 -2
  18. data/lib/mongomodel/concerns/serialization.rb +15 -6
  19. data/lib/mongomodel/embedded_document.rb +1 -0
  20. data/lib/mongomodel/railtie.rb +7 -5
  21. data/lib/mongomodel/support/scope.rb +2 -9
  22. data/lib/mongomodel/support/scope/array_methods.rb +21 -0
  23. data/lib/mongomodel/support/types/date_time.rb +18 -5
  24. data/lib/mongomodel/version.rb +1 -1
  25. data/spec/mongomodel/attributes/store_spec.rb +9 -5
  26. data/spec/mongomodel/concerns/activemodel_spec.rb +13 -13
  27. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +65 -65
  28. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +128 -121
  29. data/spec/mongomodel/concerns/attributes_spec.rb +11 -2
  30. data/spec/mongomodel/concerns/logging_spec.rb +1 -1
  31. data/spec/mongomodel/concerns/observing_spec.rb +1 -1
  32. data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +26 -10
  33. data/spec/mongomodel/concerns/timestamps_spec.rb +5 -5
  34. data/spec/mongomodel/document/indexes_spec.rb +1 -1
  35. data/spec/mongomodel/document/validations/uniqueness_spec.rb +1 -1
  36. data/spec/mongomodel/document/validations_spec.rb +1 -1
  37. data/spec/mongomodel/document_spec.rb +1 -1
  38. data/spec/mongomodel/mongomodel_spec.rb +1 -1
  39. data/spec/mongomodel/support/mongo_order_spec.rb +2 -2
  40. data/spec/mongomodel/support/paginator_spec.rb +3 -3
  41. data/spec/mongomodel/support/property_spec.rb +12 -6
  42. data/spec/mongomodel/support/scope_spec.rb +24 -14
  43. data/spec/support/helpers/document_finder_stubs.rb +5 -5
  44. data/spec/support/matchers/find_with.rb +2 -2
  45. metadata +6 -4
  46. data/Appraisals +0 -46
@@ -1,3 +1,3 @@
1
1
  module MongoModel
2
- VERSION = "0.4.9"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -27,7 +27,7 @@ module MongoModel
27
27
  properties[:as] = MongoModel::Properties::Property.new(:as, String, :as => '_custom_as')
28
28
  properties
29
29
  end
30
- let(:instance) { mock('instance', :properties => properties) }
30
+ let(:instance) { double('instance', :properties => properties) }
31
31
 
32
32
  subject { Attributes::Store.new(instance) }
33
33
 
@@ -143,9 +143,9 @@ module MongoModel
143
143
  },
144
144
  :datetime =>
145
145
  {
146
- Time.local(2008, 5, 14, 1, 2, 3, 123456) => Time.local(2008, 5, 14, 1, 2, 3, 0).to_datetime,
146
+ Time.local(2008, 5, 14, 1, 2, 3, 123456) => Time.local(2008, 5, 14, 1, 2, 3, 123000).to_datetime,
147
147
  Date.civil(2009, 11, 15) => DateTime.civil(2009, 11, 15, 0, 0, 0, 0),
148
- "Sat Jan 01 20:15:01.123456 UTC 2000" => DateTime.civil(2000, 1, 1, 20, 15, 1, 0),
148
+ "Sat Jan 01 20:15:01.123456 UTC 2000" => DateTime.civil(2000, 1, 1, 20, 15, Rational(1123, 1000), 0),
149
149
  "2009/3/4" => DateTime.civil(2009, 3, 4, 0, 0, 0, 0),
150
150
  "09:34" => lambda { |t| t.hour == 9 && t.min == 34 },
151
151
  "5:21pm" => lambda { |t| t.hour == 17 && t.min == 21 },
@@ -291,13 +291,14 @@ module MongoModel
291
291
  subject[:array] = [ 123, 'abc', 45.67, true, :bar, CustomClass.new('custom in array') ]
292
292
  subject[:date] = Date.civil(2009, 11, 15)
293
293
  subject[:time] = Time.local(2008, 5, 14, 1, 2, 3, 4, 0.5)
294
+ subject[:datetime] = DateTime.civil(2000, 1, 1, 20, 15, Rational(1123456, 1000000), 0)
294
295
  subject[:rational] = Rational(2, 3)
295
296
  subject[:openstruct] = OpenStruct.new(:abc => 123)
296
297
  subject[:custom] = CustomClass.new('custom')
297
298
  subject[:as] = "As property"
298
299
  subject[:non_property] = "Hello World"
299
300
  subject[:custom_non_property] = CustomClass.new('custom non property')
300
-
301
+
301
302
  subject.to_mongo.should include({
302
303
  'string' => 'string',
303
304
  'integer' => 42,
@@ -307,7 +308,8 @@ module MongoModel
307
308
  'hash' => { :foo => 'bar', :custom => { :name => 'custom in hash' } },
308
309
  'array' => [ 123, 'abc', 45.67, true, :bar, { :name => 'custom in array' } ],
309
310
  'date' => "2009/11/15",
310
- 'time' => Time.local(2008, 5, 14, 1, 2, 3, 4, 0),
311
+ 'time' => Time.local(2008, 5, 14, 1, 2, 3, 4, 0).utc,
312
+ 'datetime' => Time.utc(2000, 1, 1, 20, 15, 1, 123000),
311
313
  'rational' => "2/3",
312
314
  'openstruct' => { :abc => 123 },
313
315
  'custom' => { :name => 'custom' },
@@ -328,6 +330,7 @@ module MongoModel
328
330
  'array' => [ 123, 'abc', 45.67, true, :bar ],
329
331
  'date' => Time.utc(2009, 11, 15),
330
332
  'time' => Time.local(2008, 5, 14, 1, 2, 3, 4, 0.5),
333
+ 'datetime' => Time.utc(2000, 1, 1, 20, 15, 1, 123000),
331
334
  'rational' => "2/3",
332
335
  'openstruct' => { "foo" => "bar" },
333
336
  'custom' => { :name => 'custom' },
@@ -344,6 +347,7 @@ module MongoModel
344
347
  subject[:array].should == [ 123, 'abc', 45.67, true, :bar ]
345
348
  subject[:date].should == Date.civil(2009, 11, 15)
346
349
  subject[:time].should == Time.local(2008, 5, 14, 1, 2, 3, 4, 0)
350
+ subject[:datetime].should == DateTime.civil(2000, 1, 1, 20, 15, Rational(1123, 1000), 0)
347
351
  subject[:rational].should == Rational(2, 3)
348
352
  subject[:openstruct].should == OpenStruct.new(:foo => "bar")
349
353
  subject[:custom].should == CustomClass.new('custom')
@@ -1,22 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  module MongoModel
4
- shared_examples_for "ActiveModel" do
5
- require 'test/unit/assertions'
6
- include Test::Unit::Assertions
7
-
8
- include ActiveModel::Lint::Tests
9
-
10
- ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
11
- example m.gsub('_',' ') do
12
- send m
4
+ specs_for(Document, EmbeddedDocument) do
5
+ shared_examples_for "ActiveModel" do
6
+ require 'test/unit/assertions'
7
+ include Test::Unit::Assertions
8
+
9
+ include ActiveModel::Lint::Tests
10
+
11
+ ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
12
+ example m.gsub('_',' ') do
13
+ send m
14
+ end
13
15
  end
16
+
17
+ let(:model) { subject }
14
18
  end
15
19
 
16
- let(:model) { subject }
17
- end
18
-
19
- specs_for(Document, EmbeddedDocument) do
20
20
  define_class(:TestModel, described_class)
21
21
  subject { TestModel.new }
22
22
 
@@ -1,77 +1,77 @@
1
1
  require 'spec_helper'
2
2
 
3
- module MongoModel
4
- shared_examples_for "assigning correct class to belongs_to association" do
5
- define_class(:User, Document)
6
- define_class(:SpecialUser, :User)
3
+ module MongoModel
4
+ specs_for(Document, EmbeddedDocument) do
5
+ shared_examples_for "assigning correct class to belongs_to association" do
6
+ define_class(:User, Document)
7
+ define_class(:SpecialUser, :User)
7
8
 
8
- let(:user) { User.create! }
9
- let(:special_user) { SpecialUser.create! }
10
-
11
- context "when uninitialized" do
12
- it "is nil" do
13
- subject.user.should be_nil
14
- end
15
-
16
- it "is settable" do
17
- subject.user = user
18
- subject.user.should == user
19
- end
20
-
21
- it "is not truthy" do
22
- subject.user.should_not be_truthy
23
- end
24
-
25
- describe "setting a subclass type" do
26
- it "sets successfully" do
27
- subject.user = special_user
28
- subject.user.should == special_user
9
+ let(:user) { User.create! }
10
+ let(:special_user) { SpecialUser.create! }
11
+
12
+ context "when uninitialized" do
13
+ it "is nil" do
14
+ subject.user.should be_nil
29
15
  end
30
- end
31
- end
32
-
33
- context "when loading from database" do
34
- subject { Article.new(:user => user) }
35
-
36
- if specing?(EmbeddedDocument)
37
- define_class(:ArticleParent, Document) do
38
- property :article, Article
16
+
17
+ it "is settable" do
18
+ subject.user = user
19
+ subject.user.should == user
20
+ end
21
+
22
+ it "is not truthy" do
23
+ subject.user.should_not be_truthy
24
+ end
25
+
26
+ describe "setting a subclass type" do
27
+ it "sets successfully" do
28
+ subject.user = special_user
29
+ subject.user.should == special_user
30
+ end
39
31
  end
40
-
41
- let(:parent) { ArticleParent.create!(:article => subject) }
42
- let(:reloaded) { ArticleParent.find(parent.id).article }
43
- else
44
- before(:each) { subject.save! }
45
- let(:reloaded) { Article.find(subject.id) }
46
- end
47
-
48
- it "accesses the user through the association" do
49
- reloaded.user.should == user
50
- end
51
-
52
- it "is truthy" do
53
- subject.user.should be_truthy
54
- end
55
-
56
- it "allows the user to be reloaded" do
57
- user = reloaded.user.target
58
-
59
- user.should equal(reloaded.user.target)
60
- user.should equal(reloaded.user.target)
61
- user.should_not equal(reloaded.user(true).target)
62
32
  end
63
-
64
- describe "setting a subclass type" do
65
- subject { Article.new(:user => special_user) }
66
-
67
- it "loads successfully" do
68
- reloaded.user.should == special_user
33
+
34
+ context "when loading from database" do
35
+ subject { Article.new(:user => user) }
36
+
37
+ if specing?(EmbeddedDocument)
38
+ define_class(:ArticleParent, Document) do
39
+ property :article, Article
40
+ end
41
+
42
+ let(:parent) { ArticleParent.create!(:article => subject) }
43
+ let(:reloaded) { ArticleParent.find(parent.id).article }
44
+ else
45
+ before(:each) { subject.save! }
46
+ let(:reloaded) { Article.find(subject.id) }
47
+ end
48
+
49
+ it "accesses the user through the association" do
50
+ reloaded.user.should == user
51
+ end
52
+
53
+ it "is truthy" do
54
+ subject.user.should be_truthy
55
+ end
56
+
57
+ it "allows the user to be reloaded" do
58
+ user = reloaded.user.target
59
+
60
+ user.should equal(reloaded.user.target)
61
+ user.should equal(reloaded.user.target)
62
+ user.should_not equal(reloaded.user(true).target)
63
+ end
64
+
65
+ describe "setting a subclass type" do
66
+ subject { Article.new(:user => special_user) }
67
+
68
+ it "loads successfully" do
69
+ reloaded.user.should == special_user
70
+ end
69
71
  end
70
72
  end
71
73
  end
72
- end
73
-
74
- specs_for(Document, EmbeddedDocument) do
74
+
75
75
  describe "belongs_to association" do
76
76
  define_class(:Article, described_class) do
77
77
  belongs_to :user
@@ -13,130 +13,130 @@ module MongoModel
13
13
  end
14
14
  end
15
15
 
16
- shared_examples_for "accessing and manipulating a has_many :by => :ids association" do
17
- it "accesses chapters" do
18
- subject.chapters.should == [chapter1, chapter2]
19
- end
20
-
21
- it "accesses chapter ids through association" do
22
- subject.chapters.ids.should == [chapter1.id, chapter2.id]
23
- end
24
-
25
- it "has chapter ids" do
26
- subject.chapter_ids.should == [chapter1.id, chapter2.id]
27
- end
28
-
29
- it "adds chapters with <<" do
30
- subject.chapters << chapter3
31
- subject.chapters.should == [chapter1, chapter2, chapter3]
32
- subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
33
- end
34
-
35
- it "adds/change chapters with []=" do
36
- subject.chapters[2] = chapter3
37
- subject.chapters.should == [chapter1, chapter2, chapter3]
38
- subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
39
- end
40
-
41
- it "adds chapters with concat" do
42
- subject.chapters.concat([chapter3])
43
- subject.chapters.should == [chapter1, chapter2, chapter3]
44
- subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
45
- end
46
-
47
- it "inserts chapters" do
48
- subject.chapters.insert(1, chapter3)
49
- subject.chapters.should == [chapter1, chapter3, chapter2]
50
- subject.chapter_ids.should == [chapter1.id, chapter3.id, chapter2.id]
51
- end
52
-
53
- it "replaces chapters" do
54
- subject.chapters.replace([chapter2, chapter3])
55
- subject.chapters.should == [chapter2, chapter3]
56
- subject.chapter_ids.should == [chapter2.id, chapter3.id]
57
- end
58
-
59
- it "adds chapters with push" do
60
- subject.chapters.push(chapter3)
61
- subject.chapters.should == [chapter1, chapter2, chapter3]
62
- subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
63
- end
64
-
65
- it "adds chapters with unshift" do
66
- subject.chapters.unshift(chapter3)
67
- subject.chapters.should == [chapter3, chapter1, chapter2]
68
- subject.chapter_ids.should == [chapter3.id, chapter1.id, chapter2.id]
69
- end
70
-
71
- it "clears chapters" do
72
- subject.chapters.clear
73
- subject.chapters.should be_empty
74
- subject.chapter_ids.should be_empty
75
- end
76
-
77
- it "removes chapters with delete" do
78
- subject.chapters.delete(chapter1)
79
- subject.chapters.should == [chapter2]
80
- subject.chapter_ids.should == [chapter2.id]
81
- end
82
-
83
- it "removes chapters with delete_at" do
84
- subject.chapters.delete_at(0)
85
- subject.chapters.should == [chapter2]
86
- subject.chapter_ids.should == [chapter2.id]
87
- end
88
-
89
- it "removes chapters with delete_if" do
90
- subject.chapters.delete_if { |c| c.id == chapter1.id }
91
- subject.chapters.should == [chapter2]
92
- subject.chapter_ids.should == [chapter2.id]
93
- end
94
-
95
- it "builds a chapter" do
96
- chapter4 = subject.chapters.build(:id => '4')
97
- subject.chapters.should == [chapter1, chapter2, chapter4]
98
- subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
99
-
100
- chapter4.should be_a_new_record
101
- chapter4.id.should == '4'
102
- end
103
-
104
- it "creates a chapter" do
105
- chapter4 = subject.chapters.create(:id => '4')
106
- subject.chapters.should == [chapter1, chapter2, chapter4]
107
- subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
108
-
109
- chapter4.should_not be_a_new_record
110
- chapter4.id.should == '4'
111
- end
112
-
113
- it "finds chapters" do
114
- # Create bogus chapters
115
- Chapter.create!(:id => '999')
116
- Chapter.create!(:id => '998')
117
-
118
- result = subject.chapters.order(:id.desc)
119
- result.should == [chapter2, chapter1]
120
- end
121
-
122
- describe "adding a non-chapter" do
123
- def self.should_raise(message, &block)
124
- it "raises an AsssociationTypeMismatch error when #{message}" do
125
- lambda { instance_eval(&block) }.should raise_error(AssociationTypeMismatch, "expected instance of Chapter but got NonChapter")
16
+ specs_for(Document, EmbeddedDocument) do
17
+ shared_examples_for "accessing and manipulating a has_many :by => :ids association" do
18
+ it "accesses chapters" do
19
+ subject.chapters.should == [chapter1, chapter2]
20
+ end
21
+
22
+ it "accesses chapter ids through association" do
23
+ subject.chapters.ids.should == [chapter1.id, chapter2.id]
24
+ end
25
+
26
+ it "has chapter ids" do
27
+ subject.chapter_ids.should == [chapter1.id, chapter2.id]
28
+ end
29
+
30
+ it "adds chapters with <<" do
31
+ subject.chapters << chapter3
32
+ subject.chapters.should == [chapter1, chapter2, chapter3]
33
+ subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
34
+ end
35
+
36
+ it "adds/change chapters with []=" do
37
+ subject.chapters[2] = chapter3
38
+ subject.chapters.should == [chapter1, chapter2, chapter3]
39
+ subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
40
+ end
41
+
42
+ it "adds chapters with concat" do
43
+ subject.chapters.concat([chapter3])
44
+ subject.chapters.should == [chapter1, chapter2, chapter3]
45
+ subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
46
+ end
47
+
48
+ it "inserts chapters" do
49
+ subject.chapters.insert(1, chapter3)
50
+ subject.chapters.should == [chapter1, chapter3, chapter2]
51
+ subject.chapter_ids.should == [chapter1.id, chapter3.id, chapter2.id]
52
+ end
53
+
54
+ it "replaces chapters" do
55
+ subject.chapters.replace([chapter2, chapter3])
56
+ subject.chapters.should == [chapter2, chapter3]
57
+ subject.chapter_ids.should == [chapter2.id, chapter3.id]
58
+ end
59
+
60
+ it "adds chapters with push" do
61
+ subject.chapters.push(chapter3)
62
+ subject.chapters.should == [chapter1, chapter2, chapter3]
63
+ subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter3.id]
64
+ end
65
+
66
+ it "adds chapters with unshift" do
67
+ subject.chapters.unshift(chapter3)
68
+ subject.chapters.should == [chapter3, chapter1, chapter2]
69
+ subject.chapter_ids.should == [chapter3.id, chapter1.id, chapter2.id]
70
+ end
71
+
72
+ it "clears chapters" do
73
+ subject.chapters.clear
74
+ subject.chapters.should be_empty
75
+ subject.chapter_ids.should be_empty
76
+ end
77
+
78
+ it "removes chapters with delete" do
79
+ subject.chapters.delete(chapter1)
80
+ subject.chapters.should == [chapter2]
81
+ subject.chapter_ids.should == [chapter2.id]
82
+ end
83
+
84
+ it "removes chapters with delete_at" do
85
+ subject.chapters.delete_at(0)
86
+ subject.chapters.should == [chapter2]
87
+ subject.chapter_ids.should == [chapter2.id]
88
+ end
89
+
90
+ it "removes chapters with delete_if" do
91
+ subject.chapters.delete_if { |c| c.id == chapter1.id }
92
+ subject.chapters.should == [chapter2]
93
+ subject.chapter_ids.should == [chapter2.id]
94
+ end
95
+
96
+ it "builds a chapter" do
97
+ chapter4 = subject.chapters.build(:id => '4')
98
+ subject.chapters.should == [chapter1, chapter2, chapter4]
99
+ subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
100
+
101
+ chapter4.should be_a_new_record
102
+ chapter4.id.should == '4'
103
+ end
104
+
105
+ it "creates a chapter" do
106
+ chapter4 = subject.chapters.create(:id => '4')
107
+ subject.chapters.should == [chapter1, chapter2, chapter4]
108
+ subject.chapter_ids.should == [chapter1.id, chapter2.id, chapter4.id]
109
+
110
+ chapter4.should_not be_a_new_record
111
+ chapter4.id.should == '4'
112
+ end
113
+
114
+ it "finds chapters" do
115
+ # Create bogus chapters
116
+ Chapter.create!(:id => '999')
117
+ Chapter.create!(:id => '998')
118
+
119
+ result = subject.chapters.order(:id.desc)
120
+ result.should == [chapter2, chapter1]
121
+ end
122
+
123
+ describe "adding a non-chapter" do
124
+ def self.should_raise(message, &block)
125
+ it "raises an AsssociationTypeMismatch error when #{message}" do
126
+ lambda { instance_eval(&block) }.should raise_error(AssociationTypeMismatch, "expected instance of Chapter but got NonChapter")
127
+ end
126
128
  end
129
+
130
+ should_raise("assigning an array containing non-chapters") { subject.chapters = [nonchapter] }
131
+ should_raise("adding a non-chapter using <<") { subject.chapters << nonchapter }
132
+ should_raise("adding non-chapters with concat") { subject.chapters.concat([nonchapter]) }
133
+ should_raise("inserting chapters") { subject.chapters.insert(1, nonchapter) }
134
+ should_raise("replacing chapters") { subject.chapters.replace([nonchapter]) }
135
+ should_raise("addding chapters with push") { subject.chapters.push(nonchapter) }
136
+ should_raise("addding chapters with unshift") { subject.chapters.unshift(nonchapter) }
127
137
  end
128
-
129
- should_raise("assigning an array containing non-chapters") { subject.chapters = [nonchapter] }
130
- should_raise("adding a non-chapter using <<") { subject.chapters << nonchapter }
131
- should_raise("adding non-chapters with concat") { subject.chapters.concat([nonchapter]) }
132
- should_raise("inserting chapters") { subject.chapters.insert(1, nonchapter) }
133
- should_raise("replacing chapters") { subject.chapters.replace([nonchapter]) }
134
- should_raise("addding chapters with push") { subject.chapters.push(nonchapter) }
135
- should_raise("addding chapters with unshift") { subject.chapters.unshift(nonchapter) }
136
138
  end
137
- end
138
-
139
- specs_for(Document, EmbeddedDocument) do
139
+
140
140
  describe "has_many :by => :ids association" do
141
141
  define_class(:Chapter, Document)
142
142
  define_class(:IllustratedChapter, :Chapter)
@@ -186,6 +186,13 @@ module MongoModel
186
186
  end
187
187
 
188
188
  it_should_behave_like "accessing and manipulating a has_many :by => :ids association"
189
+
190
+ context "when child objects are destroyed" do
191
+ it "does not load the deleted child objects" do
192
+ chapter1.destroy
193
+ subject.chapters.should === [chapter2]
194
+ end
195
+ end
189
196
  end
190
197
 
191
198
  describe "with :dependent => :destroy option" do