mongomodel 0.5.5 → 0.5.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 (156) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +23 -11
  3. data/gemfiles/rails-3.2.gemfile +2 -2
  4. data/gemfiles/rails-4-observers.gemfile +1 -1
  5. data/gemfiles/rails-4.1.gemfile +2 -2
  6. data/gemfiles/{mongoid.gemfile → rails-4.2.gemfile} +2 -3
  7. data/gemfiles/{mongo_mapper.gemfile → rails-5.0.gemfile} +2 -3
  8. data/gemfiles/rails-5.1.gemfile +10 -0
  9. data/gemfiles/rails-5.2.gemfile +10 -0
  10. data/lib/mongomodel.rb +15 -15
  11. data/lib/mongomodel/attributes/mongo.rb +7 -7
  12. data/lib/mongomodel/attributes/store.rb +4 -4
  13. data/lib/mongomodel/attributes/typecasting.rb +7 -7
  14. data/lib/mongomodel/compatibility/mongo_mapper.rb +3 -3
  15. data/lib/mongomodel/compatibility/mongoid.rb +3 -3
  16. data/lib/mongomodel/concerns/abstract_class.rb +3 -3
  17. data/lib/mongomodel/concerns/activemodel.rb +4 -4
  18. data/lib/mongomodel/concerns/associations.rb +8 -8
  19. data/lib/mongomodel/concerns/associations/base/association.rb +5 -5
  20. data/lib/mongomodel/concerns/associations/base/definition.rb +4 -4
  21. data/lib/mongomodel/concerns/associations/base/proxy.rb +1 -1
  22. data/lib/mongomodel/concerns/associations/belongs_to.rb +19 -19
  23. data/lib/mongomodel/concerns/associations/has_many_by_foreign_key.rb +36 -36
  24. data/lib/mongomodel/concerns/associations/has_many_by_ids.rb +34 -34
  25. data/lib/mongomodel/concerns/attribute_methods.rb +10 -10
  26. data/lib/mongomodel/concerns/attribute_methods/before_type_cast.rb +4 -4
  27. data/lib/mongomodel/concerns/attribute_methods/dirty.rb +95 -13
  28. data/lib/mongomodel/concerns/attribute_methods/forbidden.rb +1 -1
  29. data/lib/mongomodel/concerns/attribute_methods/multi_parameter_assignment.rb +6 -6
  30. data/lib/mongomodel/concerns/attribute_methods/nested.rb +18 -18
  31. data/lib/mongomodel/concerns/attribute_methods/protected.rb +3 -3
  32. data/lib/mongomodel/concerns/attribute_methods/query.rb +3 -3
  33. data/lib/mongomodel/concerns/attribute_methods/read.rb +4 -4
  34. data/lib/mongomodel/concerns/attribute_methods/write.rb +4 -4
  35. data/lib/mongomodel/concerns/attributes.rb +18 -18
  36. data/lib/mongomodel/concerns/callbacks.rb +7 -7
  37. data/lib/mongomodel/concerns/document_parent.rb +2 -2
  38. data/lib/mongomodel/concerns/logging.rb +2 -2
  39. data/lib/mongomodel/concerns/map_reduce.rb +11 -11
  40. data/lib/mongomodel/concerns/pretty_inspect.rb +3 -3
  41. data/lib/mongomodel/concerns/properties.rb +18 -18
  42. data/lib/mongomodel/concerns/record_status.rb +9 -13
  43. data/lib/mongomodel/concerns/serialization.rb +4 -4
  44. data/lib/mongomodel/concerns/timestamps.rb +4 -4
  45. data/lib/mongomodel/concerns/translation.rb +2 -2
  46. data/lib/mongomodel/concerns/validations.rb +5 -5
  47. data/lib/mongomodel/concerns/validations/associated.rb +1 -1
  48. data/lib/mongomodel/document.rb +6 -6
  49. data/lib/mongomodel/document/callbacks.rb +15 -21
  50. data/lib/mongomodel/document/collection_modifiers.rb +5 -5
  51. data/lib/mongomodel/document/dynamic_finders.rb +1 -1
  52. data/lib/mongomodel/document/indexes.rb +19 -19
  53. data/lib/mongomodel/document/optimistic_locking.rb +7 -7
  54. data/lib/mongomodel/document/persistence.rb +23 -23
  55. data/lib/mongomodel/document/scopes.rb +20 -20
  56. data/lib/mongomodel/document/validations.rb +6 -6
  57. data/lib/mongomodel/document/validations/uniqueness.rb +11 -11
  58. data/lib/mongomodel/embedded_document.rb +11 -11
  59. data/lib/mongomodel/locale/en.yml +0 -1
  60. data/lib/mongomodel/log_subscriber.rb +5 -5
  61. data/lib/mongomodel/railtie.rb +13 -13
  62. data/lib/mongomodel/support/collection.rb +31 -31
  63. data/lib/mongomodel/support/configuration.rb +11 -11
  64. data/lib/mongomodel/support/core_extensions.rb +1 -1
  65. data/lib/mongomodel/support/dynamic_finder.rb +12 -12
  66. data/lib/mongomodel/support/exceptions.rb +6 -6
  67. data/lib/mongomodel/support/instrumented_collection.rb +20 -20
  68. data/lib/mongomodel/support/map.rb +33 -33
  69. data/lib/mongomodel/support/mongo_operator.rb +6 -6
  70. data/lib/mongomodel/support/mongo_options.rb +18 -18
  71. data/lib/mongomodel/support/mongo_order.rb +16 -16
  72. data/lib/mongomodel/support/paginator.rb +8 -8
  73. data/lib/mongomodel/support/reference.rb +10 -10
  74. data/lib/mongomodel/support/scope.rb +37 -37
  75. data/lib/mongomodel/support/scope/array_methods.rb +1 -1
  76. data/lib/mongomodel/support/scope/batches.rb +1 -1
  77. data/lib/mongomodel/support/scope/dynamic_finders.rb +1 -1
  78. data/lib/mongomodel/support/scope/finder_methods.rb +7 -7
  79. data/lib/mongomodel/support/scope/load_methods.rb +1 -1
  80. data/lib/mongomodel/support/scope/pagination.rb +1 -1
  81. data/lib/mongomodel/support/scope/query_methods.rb +6 -6
  82. data/lib/mongomodel/support/scope/spawn_methods.rb +8 -8
  83. data/lib/mongomodel/support/types.rb +2 -2
  84. data/lib/mongomodel/support/types/array.rb +1 -1
  85. data/lib/mongomodel/support/types/boolean.rb +3 -3
  86. data/lib/mongomodel/support/types/custom.rb +3 -3
  87. data/lib/mongomodel/support/types/date.rb +2 -2
  88. data/lib/mongomodel/support/types/date_time.rb +6 -16
  89. data/lib/mongomodel/support/types/float.rb +1 -1
  90. data/lib/mongomodel/support/types/hash.rb +1 -1
  91. data/lib/mongomodel/support/types/integer.rb +13 -10
  92. data/lib/mongomodel/support/types/object.rb +5 -5
  93. data/lib/mongomodel/support/types/rational.rb +3 -3
  94. data/lib/mongomodel/support/types/time.rb +2 -2
  95. data/lib/mongomodel/version.rb +1 -1
  96. data/lib/rails/generators/mongo_model/config/templates/mongomodel.yml +3 -4
  97. data/lib/rails/generators/mongo_model/model/model_generator.rb +3 -3
  98. data/mongomodel.gemspec +5 -4
  99. data/spec/mongomodel/attributes/store_spec.rb +21 -21
  100. data/spec/mongomodel/concerns/activemodel_spec.rb +4 -4
  101. data/spec/mongomodel/concerns/associations/base/association_spec.rb +12 -12
  102. data/spec/mongomodel/concerns/associations/belongs_to_spec.rb +34 -21
  103. data/spec/mongomodel/concerns/associations/has_many_by_foreign_key_spec.rb +53 -53
  104. data/spec/mongomodel/concerns/associations/has_many_by_ids_spec.rb +30 -30
  105. data/spec/mongomodel/concerns/attribute_methods/before_type_cast_spec.rb +7 -7
  106. data/spec/mongomodel/concerns/attribute_methods/dirty_spec.rb +45 -41
  107. data/spec/mongomodel/concerns/attribute_methods/multi_parameter_assignment_spec.rb +7 -7
  108. data/spec/mongomodel/concerns/attribute_methods/nested_spec.rb +31 -31
  109. data/spec/mongomodel/concerns/attribute_methods/protected_spec.rb +15 -15
  110. data/spec/mongomodel/concerns/attribute_methods/query_spec.rb +19 -19
  111. data/spec/mongomodel/concerns/attribute_methods/read_spec.rb +9 -9
  112. data/spec/mongomodel/concerns/attribute_methods/write_spec.rb +6 -6
  113. data/spec/mongomodel/concerns/attribute_methods_spec.rb +13 -13
  114. data/spec/mongomodel/concerns/attributes_spec.rb +34 -34
  115. data/spec/mongomodel/concerns/callbacks_spec.rb +25 -21
  116. data/spec/mongomodel/concerns/logging_spec.rb +5 -3
  117. data/spec/mongomodel/concerns/map_reduce_spec.rb +19 -19
  118. data/spec/mongomodel/concerns/observing_spec.rb +3 -3
  119. data/spec/mongomodel/concerns/pretty_inspect_spec.rb +10 -10
  120. data/spec/mongomodel/concerns/properties_spec.rb +11 -11
  121. data/spec/mongomodel/concerns/serialization/json_serialization_spec.rb +13 -13
  122. data/spec/mongomodel/concerns/timestamps_spec.rb +39 -39
  123. data/spec/mongomodel/concerns/validations_spec.rb +41 -38
  124. data/spec/mongomodel/document/callbacks_spec.rb +20 -16
  125. data/spec/mongomodel/document/collection_modifiers_spec.rb +16 -16
  126. data/spec/mongomodel/document/dynamic_finders_spec.rb +46 -46
  127. data/spec/mongomodel/document/finders_spec.rb +15 -15
  128. data/spec/mongomodel/document/indexes_spec.rb +29 -29
  129. data/spec/mongomodel/document/optimistic_locking_spec.rb +16 -16
  130. data/spec/mongomodel/document/persistence_spec.rb +39 -39
  131. data/spec/mongomodel/document/scopes_spec.rb +17 -17
  132. data/spec/mongomodel/document/validations/uniqueness_spec.rb +46 -46
  133. data/spec/mongomodel/document/validations_spec.rb +35 -35
  134. data/spec/mongomodel/document_spec.rb +19 -19
  135. data/spec/mongomodel/embedded_document_spec.rb +19 -19
  136. data/spec/mongomodel/mongomodel_spec.rb +7 -6
  137. data/spec/mongomodel/support/collection_spec.rb +54 -54
  138. data/spec/mongomodel/support/configuration_spec.rb +1 -1
  139. data/spec/mongomodel/support/map_spec.rb +66 -66
  140. data/spec/mongomodel/support/mongo_operator_spec.rb +5 -5
  141. data/spec/mongomodel/support/mongo_options_spec.rb +42 -42
  142. data/spec/mongomodel/support/mongo_order_spec.rb +24 -24
  143. data/spec/mongomodel/support/paginator_spec.rb +15 -15
  144. data/spec/mongomodel/support/property_spec.rb +29 -23
  145. data/spec/mongomodel/support/scope_spec.rb +205 -204
  146. data/spec/spec_helper.rb +13 -2
  147. data/spec/support/callbacks.rb +3 -8
  148. data/spec/support/helpers/define_class.rb +7 -7
  149. data/spec/support/helpers/document_finder_stubs.rb +6 -6
  150. data/spec/support/helpers/specs_for.rb +1 -1
  151. data/spec/support/helpers/validations.rb +1 -1
  152. data/spec/support/matchers/find_with.rb +8 -8
  153. data/spec/support/matchers/respond_to_boolean.rb +3 -3
  154. data/spec/support/matchers/run_callbacks.rb +6 -9
  155. data/spec/support/models.rb +5 -5
  156. metadata +23 -7
@@ -6,16 +6,16 @@ module MongoModel
6
6
  source_root File.expand_path('../templates', __FILE__)
7
7
 
8
8
  argument :attributes, :type => :array, :default => [], :banner => "field:type field:type"
9
-
9
+
10
10
  class_option :timestamps, :type => :boolean, :aliases => "-T", :default => true, :desc => "Add timestamp fields (created_at, updated_at)"
11
11
  class_option :embedded, :type => :boolean, :aliases => "-E", :default => false, :desc => "Inherit from EmbeddedDocument"
12
12
 
13
13
  check_class_collision
14
-
14
+
15
15
  def create_model_file
16
16
  template 'model.rb', File.join('app/models', class_path, "#{file_name}.rb")
17
17
  end
18
-
18
+
19
19
  hook_for :test_framework
20
20
  end
21
21
  end
@@ -14,14 +14,15 @@ Gem::Specification.new do |s|
14
14
 
15
15
  s.required_rubygems_version = ">= 1.3.6"
16
16
  s.rubyforge_project = "mongomodel"
17
-
17
+
18
18
  s.add_dependency "activesupport", ">= 3.1"
19
19
  s.add_dependency "activemodel", ">= 3.1"
20
20
  s.add_dependency "mongo", "~> 1.8"
21
21
 
22
- s.add_development_dependency "bundler", ">= 1.0"
23
- s.add_development_dependency "rspec", "~> 2.8"
24
- s.add_development_dependency "minitest", ">= 4.2"
22
+ s.add_development_dependency "bundler", ">= 1.0"
23
+ s.add_development_dependency "rspec", "~> 3.5"
24
+ s.add_development_dependency "rspec-its", "~> 1.2"
25
+ s.add_development_dependency "minitest", ">= 4.2"
25
26
 
26
27
  s.files = `git ls-files`.split("\n")
27
28
  s.require_path = 'lib'
@@ -28,18 +28,18 @@ module MongoModel
28
28
  properties
29
29
  end
30
30
  let(:instance) { double('instance', :properties => properties) }
31
-
31
+
32
32
  subject { Attributes::Store.new(instance) }
33
-
33
+
34
34
  it "sets default property values" do
35
35
  subject.keys.should == properties.keys
36
36
  subject[:default].should == 'Default'
37
37
  end
38
-
38
+
39
39
  it "sets default property value using mongomodel_default if defined by class" do
40
40
  subject[:custom_default].should == CustomClassWithDefault.new("Custom class default")
41
41
  end
42
-
42
+
43
43
  describe "setting to nil" do
44
44
  specify "all property types should be nullable" do
45
45
  properties.keys.each do |property|
@@ -48,12 +48,12 @@ module MongoModel
48
48
  end
49
49
  end
50
50
  end
51
-
51
+
52
52
  it "sets attributes that aren't properties" do
53
53
  subject[:non_property] = "Hello World"
54
54
  subject[:non_property].should == "Hello World"
55
55
  end
56
-
56
+
57
57
  describe "type-casting" do
58
58
  TypeCastExamples = {
59
59
  :string =>
@@ -163,14 +163,14 @@ module MongoModel
163
163
  { :mykey => "Hello world" } => OpenStruct.new(:mykey => "Hello world")
164
164
  }
165
165
  }
166
-
166
+
167
167
  TypeCastExamples.each do |type, examples|
168
168
  context "assigning to #{type} property" do
169
169
  examples.each do |assigned, expected|
170
170
  if expected.is_a?(Proc)
171
171
  it "casts #{assigned.inspect} to match proc" do
172
172
  subject[type] = assigned
173
- expected.call(subject[type]).should be_true
173
+ expected.call(subject[type]).should be true
174
174
  end
175
175
  else
176
176
  it "casts #{assigned.inspect} to #{expected.inspect}" do
@@ -181,24 +181,24 @@ module MongoModel
181
181
  end
182
182
  end
183
183
  end
184
-
184
+
185
185
  context "assigning to custom property" do
186
186
  before(:each) do
187
187
  @custom = CustomClass.new('instance name')
188
188
  end
189
-
189
+
190
190
  it "does not alter instances of CustomClass" do
191
191
  subject[:custom] = @custom
192
192
  subject[:custom].should == @custom
193
193
  end
194
-
194
+
195
195
  it "casts strings to CustomClass" do
196
196
  subject[:custom] = "foobar"
197
197
  subject[:custom].should == CustomClass.new('foobar')
198
198
  end
199
199
  end
200
200
  end
201
-
201
+
202
202
  describe "#before_type_cast" do
203
203
  BeforeTypeCastExamples = {
204
204
  :string => [ "abc", 123 ],
@@ -213,7 +213,7 @@ module MongoModel
213
213
  :date => [ Date.civil(2009, 11, 15), Time.local(2008, 12, 3, 0, 0, 0, 0), "2009/3/4", "Sat Jan 01 20:15:01 UTC 2000" ],
214
214
  :time => [ Time.local(2008, 5, 14, 1, 2, 3, 4), Date.civil(2009, 11, 15), "Sat Jan 01 20:15:01 UTC 2000", "2009/3/4" ]
215
215
  }
216
-
216
+
217
217
  BeforeTypeCastExamples.each do |type, examples|
218
218
  context "assigning to #{type} property" do
219
219
  examples.each do |example|
@@ -225,7 +225,7 @@ module MongoModel
225
225
  end
226
226
  end
227
227
  end
228
-
228
+
229
229
  describe "#has?" do
230
230
  TrueExamples = {
231
231
  :string => [ 'abc', '1' ],
@@ -241,7 +241,7 @@ module MongoModel
241
241
  :openstruct => [ {} ],
242
242
  :custom => [ CustomClass.new('foobar'), 'baz' ]
243
243
  }
244
-
244
+
245
245
  FalseExamples = {
246
246
  :string => [ nil, '' ],
247
247
  :integer => [ nil, 0 ],
@@ -256,7 +256,7 @@ module MongoModel
256
256
  :openstruct => [ nil ],
257
257
  :custom => [ nil ]
258
258
  }
259
-
259
+
260
260
  TrueExamples.each do |type, examples|
261
261
  context "assigning to #{type} property" do
262
262
  examples.each do |example|
@@ -267,7 +267,7 @@ module MongoModel
267
267
  end
268
268
  end
269
269
  end
270
-
270
+
271
271
  FalseExamples.each do |type, examples|
272
272
  context "assigning to #{type} property" do
273
273
  examples.each do |example|
@@ -279,7 +279,7 @@ module MongoModel
279
279
  end
280
280
  end
281
281
  end
282
-
282
+
283
283
  describe "serialization" do
284
284
  it "converts to mongo representation" do
285
285
  subject[:string] = 'string'
@@ -298,7 +298,7 @@ module MongoModel
298
298
  subject[:as] = "As property"
299
299
  subject[:non_property] = "Hello World"
300
300
  subject[:custom_non_property] = CustomClass.new('custom non property')
301
-
301
+
302
302
  subject.to_mongo.should include({
303
303
  'string' => 'string',
304
304
  'integer' => 42,
@@ -318,7 +318,7 @@ module MongoModel
318
318
  'custom_non_property' => { :name => 'custom non property' },
319
319
  })
320
320
  end
321
-
321
+
322
322
  it "loads from mongo representation" do
323
323
  subject.from_mongo!({
324
324
  'string' => 'string',
@@ -337,7 +337,7 @@ module MongoModel
337
337
  '_custom_as' => "As property",
338
338
  'custom_non_property' => { :name => 'custom non property' }
339
339
  })
340
-
340
+
341
341
  subject[:string].should == 'string'
342
342
  subject[:integer].should == 42
343
343
  subject[:float].should == 123.45
@@ -8,9 +8,9 @@ module MongoModel
8
8
  rescue LoadError
9
9
  require 'minitest/unit'
10
10
  end
11
-
11
+
12
12
  include Minitest::Assertions
13
-
13
+
14
14
  attr_accessor :assertions
15
15
  before(:all) { self.assertions = 0 }
16
16
 
@@ -24,10 +24,10 @@ module MongoModel
24
24
 
25
25
  let(:model) { subject }
26
26
  end
27
-
27
+
28
28
  define_class(:TestModel, described_class)
29
29
  subject { TestModel.new }
30
-
30
+
31
31
  it_should_behave_like "ActiveModel"
32
32
  end
33
33
  end
@@ -7,47 +7,47 @@ module MongoModel
7
7
  define_class(:Chapter, MongoModel::Document)
8
8
  define_class(:IllustratedChapter, :Chapter)
9
9
  define_class(:NonChapter, MongoModel::Document)
10
-
10
+
11
11
  let(:klass) { Chapter }
12
12
  let(:definition) { double(:klass => klass) }
13
13
  let(:instance) { double }
14
-
14
+
15
15
  subject! { Association.new(definition, instance) }
16
-
16
+
17
17
  describe "#ensure_class" do
18
18
  it "accepts instances of the definition class" do
19
19
  subject.ensure_class(Chapter.new)
20
20
  end
21
-
21
+
22
22
  it "accepts instances of a subclass of the definition class" do
23
23
  subject.ensure_class(IllustratedChapter.new)
24
24
  end
25
-
25
+
26
26
  it "raises an error if passed an object that is not an instance of the definition class" do
27
27
  lambda {
28
28
  subject.ensure_class(NonChapter.new)
29
29
  }.should raise_error(MongoModel::AssociationTypeMismatch)
30
30
  end
31
-
31
+
32
32
  it "accepts instances of the definition class that have been reloaded" do
33
33
  # Ensure Chapter class name is cached on the original class
34
34
  Chapter.name
35
-
35
+
36
36
  Object.send(:remove_const, :Chapter)
37
37
  Object.const_set(:Chapter, Class.new(MongoModel::Document))
38
-
38
+
39
39
  subject.ensure_class(Chapter.new)
40
40
  end
41
-
41
+
42
42
  it "accepts stale instances of a class that has been reloaded" do
43
43
  chapter = Chapter.new
44
-
44
+
45
45
  Object.send(:remove_const, :Chapter)
46
46
  Object.const_set(:Chapter, Class.new(MongoModel::Document))
47
-
47
+
48
48
  definition = double(:klass => Chapter)
49
49
  association = Association.new(definition, instance)
50
-
50
+
51
51
  association.ensure_class(chapter)
52
52
  end
53
53
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- module MongoModel
3
+ module MongoModel
4
4
  specs_for(Document, EmbeddedDocument) do
5
5
  shared_examples_for "assigning correct class to belongs_to association" do
6
6
  define_class(:User, Document)
@@ -71,36 +71,36 @@ module MongoModel
71
71
  end
72
72
  end
73
73
  end
74
-
74
+
75
75
  describe "belongs_to association" do
76
76
  define_class(:Article, described_class) do
77
77
  belongs_to :user
78
78
  end
79
-
79
+
80
80
  subject { Article.new }
81
-
81
+
82
82
  it_should_behave_like "assigning correct class to belongs_to association"
83
-
83
+
84
84
  describe "setting a different class type" do
85
85
  define_class(:NonUser, Document)
86
-
86
+
87
87
  let(:non_user) { NonUser.create! }
88
-
88
+
89
89
  it "raises a AssociationTypeMismatch exception" do
90
90
  lambda { subject.user = non_user }.should raise_error(AssociationTypeMismatch, "User expected, got NonUser")
91
91
  end
92
92
  end
93
-
93
+
94
94
  describe "#build_user" do
95
95
  let(:user) { subject.build_user(:id => '123') }
96
-
96
+
97
97
  it "returns a new unsaved user with the given attributes" do
98
98
  user.should be_an_instance_of(User)
99
99
  user.should be_a_new_record
100
100
  user.id.should == '123'
101
101
  end
102
102
  end
103
-
103
+
104
104
  describe "#create_user" do
105
105
  it "returns a new saved user with the given attributes" do
106
106
  user = subject.create_user(:id => '123')
@@ -110,45 +110,58 @@ module MongoModel
110
110
  end
111
111
  end
112
112
  end
113
-
113
+
114
+ describe "belongs_to association with custom foreign_key" do
115
+ define_class(:Article, described_class) do
116
+ belongs_to :user, :foreign_key => :author_id
117
+ end
118
+
119
+ subject { Article.new }
120
+
121
+ it "uses the foreign key as the reference property" do
122
+ user = subject.build_user(:id => '123')
123
+ subject.author_id.should == '123'
124
+ end
125
+ end
126
+
114
127
  describe "polymorphic belongs_to association" do
115
128
  define_class(:Article, described_class) do
116
129
  belongs_to :user, :polymorphic => true
117
130
  end
118
-
131
+
119
132
  subject { Article.new }
120
-
133
+
121
134
  define_class(:NonUser, Document)
122
-
135
+
123
136
  let(:non_user) { NonUser.create! }
124
-
137
+
125
138
  it_should_behave_like "assigning correct class to belongs_to association"
126
-
139
+
127
140
  describe "setting a different class type" do
128
141
  it "sets successfully" do
129
142
  subject.user = non_user
130
143
  subject.user.should == non_user
131
144
  end
132
145
  end
133
-
146
+
134
147
  context "when loading from database" do
135
148
  subject { Article.new(:user => user) }
136
-
149
+
137
150
  if specing?(EmbeddedDocument)
138
151
  define_class(:ArticleParent, Document) do
139
152
  property :article, Article
140
153
  end
141
-
154
+
142
155
  let(:parent) { ArticleParent.create!(:article => subject) }
143
156
  let(:reloaded) { ArticleParent.find(parent.id).article }
144
157
  else
145
158
  before(:each) { subject.save! }
146
159
  let(:reloaded) { Article.find(subject.id) }
147
160
  end
148
-
161
+
149
162
  describe "setting a different class type" do
150
163
  subject { Article.new(:user => non_user) }
151
-
164
+
152
165
  it "loads successfully" do
153
166
  reloaded.user.should == non_user
154
167
  end
@@ -6,16 +6,16 @@ module MongoModel
6
6
  define_class(:MyBook, Document) do
7
7
  has_many :chapters
8
8
  end
9
-
9
+
10
10
  it "defaults to :by => :foreign_key" do
11
11
  MyBook.associations[:chapters].should be_a(Associations::HasManyByForeignKey)
12
12
  end
13
-
13
+
14
14
  it "sets default inverse_of value" do
15
15
  MyBook.associations[:chapters].inverse_of.should == :my_book
16
16
  end
17
17
  end
18
-
18
+
19
19
  describe "has_many :by => :foreign_key association" do
20
20
  define_class(:Chapter, Document) do
21
21
  belongs_to :book
@@ -25,218 +25,218 @@ module MongoModel
25
25
  has_many :chapters, :by => :foreign_key, :limit => 5, :order => :id.asc
26
26
  end
27
27
  define_class(:NonChapter, Document)
28
-
28
+
29
29
  let(:chapter1) { Chapter.create!(:id => '1') }
30
30
  let(:chapter2) { IllustratedChapter.create!(:id => '2') }
31
31
  let(:chapter3) { Chapter.create!(:id => '3') }
32
32
  let(:nonchapter) { NonChapter.create! }
33
-
33
+
34
34
  context "when uninitialized" do
35
35
  subject { Book.new }
36
-
36
+
37
37
  it "is empty" do
38
38
  subject.chapters.should be_empty
39
39
  end
40
40
  end
41
-
41
+
42
42
  shared_examples_for "accessing and manipulating a has_many :by => :foreign_key association" do
43
43
  it "accesses chapters" do
44
44
  subject.chapters.should include(chapter1, chapter2)
45
45
  end
46
-
46
+
47
47
  it "accesses chapter ids through association" do
48
48
  subject.chapters.ids.should include(chapter1.id, chapter2.id)
49
49
  end
50
-
50
+
51
51
  it "adds chapters with <<" do
52
52
  subject.chapters << chapter3
53
53
  subject.chapters.should include(chapter1, chapter2, chapter3)
54
54
  chapter3.book.should == subject
55
55
  end
56
-
56
+
57
57
  it "adds/change chapters with []=" do
58
58
  subject.chapters[2] = chapter3
59
59
  subject.chapters.should include(chapter1, chapter2, chapter3)
60
60
  chapter3.book.should == subject
61
61
  end
62
-
62
+
63
63
  it "replaces chapters with []=" do
64
64
  subject.chapters[1] = chapter3
65
65
  subject.chapters.should include(chapter1, chapter3)
66
66
  subject.chapters.should_not include(chapter2)
67
67
  #chapter2.book.should be_nil
68
68
  end
69
-
69
+
70
70
  it "adds chapters with concat" do
71
71
  subject.chapters.concat([chapter3])
72
72
  subject.chapters.should include(chapter1, chapter2, chapter3)
73
73
  chapter3.book.should == subject
74
74
  end
75
-
75
+
76
76
  it "inserts chapters" do
77
77
  subject.chapters.insert(1, chapter3)
78
78
  subject.chapters.should include(chapter1, chapter2, chapter3)
79
79
  chapter3.book.should == subject
80
80
  end
81
-
81
+
82
82
  # it "should replace chapters" do
83
83
  # subject.chapters.replace([chapter2, chapter3])
84
84
  # subject.chapters.should == [chapter2, chapter3]
85
85
  # subject.chapter_ids.should == [chapter2.id, chapter3.id]
86
86
  # end
87
-
87
+
88
88
  it "adds chapters with push" do
89
89
  subject.chapters.push(chapter3)
90
90
  subject.chapters.should include(chapter1, chapter2, chapter3)
91
91
  chapter3.book.should == subject
92
92
  end
93
-
93
+
94
94
  it "adds chapters with unshift" do
95
95
  subject.chapters.unshift(chapter3)
96
96
  subject.chapters.should include(chapter3, chapter1, chapter2)
97
97
  chapter3.book.should == subject
98
98
  end
99
-
99
+
100
100
  # it "should clear chapters" do
101
101
  # subject.chapters.clear
102
102
  # subject.chapters.should be_empty
103
103
  # [chapter1, chapter2].each { |c| c.book.should be_nil }
104
104
  # end
105
-
105
+
106
106
  it "removes chapters with delete" do
107
107
  subject.chapters.delete(chapter1)
108
108
  subject.chapters.should == [chapter2]
109
109
  chapter1.book.should be_nil
110
110
  end
111
-
111
+
112
112
  it "removes chapters with delete_at" do
113
113
  subject.chapters.delete_at(0)
114
114
  subject.chapters.should == [chapter2]
115
115
  #chapter1.book.should be_nil
116
116
  end
117
-
117
+
118
118
  # it "should remove chapters with delete_if" do
119
119
  # subject.chapters.delete_if { |c| c.id == chapter1.id }
120
120
  # subject.chapters.should == [chapter2]
121
121
  # subject.chapter_ids.should == [chapter2.id]
122
122
  # end
123
-
123
+
124
124
  it "builds a chapter" do
125
125
  chapter4 = subject.chapters.build(:id => '4')
126
126
  subject.chapters.should include(chapter1, chapter2, chapter4)
127
-
127
+
128
128
  chapter4.should be_a_new_record
129
129
  chapter4.id.should == '4'
130
130
  chapter4.book.should == subject
131
131
  chapter4.book_id.should == subject.id
132
132
  end
133
-
133
+
134
134
  it "creates a chapter" do
135
135
  chapter4 = subject.chapters.create(:id => '4')
136
136
  subject.chapters.should == [chapter1, chapter2, chapter4]
137
-
137
+
138
138
  chapter4.should_not be_a_new_record
139
139
  chapter4.id.should == '4'
140
140
  chapter4.book.should == subject
141
141
  chapter4.book_id.should == subject.id
142
142
  end
143
-
143
+
144
144
  it "finds chapters" do
145
145
  # Create bogus chapters
146
146
  Chapter.create!(:id => '999')
147
147
  Chapter.create!(:id => '998')
148
-
148
+
149
149
  result = subject.chapters.order(:id.desc)
150
150
  result.should == [chapter2, chapter1]
151
151
  end
152
-
152
+
153
153
  it "finds chapters with association options" do
154
154
  # Create bogus chapters
155
155
  10.times { subject.chapters.create! }
156
-
156
+
157
157
  subject.chapters.all.size.should == 5 # limit clause
158
158
  end
159
-
159
+
160
160
  it "supports scope select method" do
161
161
  subject.chapters.select(:id, :_type, :book_id).should == [chapter1, chapter2]
162
162
  end
163
-
163
+
164
164
  it "supports array select method" do
165
165
  subject.chapters.select { |c| c.is_a?(IllustratedChapter) }.should == [chapter2]
166
166
  end
167
167
  end
168
-
168
+
169
169
  context "new instance with chapters set" do
170
170
  subject { Book.new(:chapters => [chapter1, chapter2]) }
171
171
  it_should_behave_like "accessing and manipulating a has_many :by => :foreign_key association"
172
172
  end
173
-
173
+
174
174
  context "when loaded from database" do
175
175
  let(:book) { Book.create!(:chapters => [chapter1, chapter2]) }
176
176
  subject { Book.find(book.id) }
177
177
  it_should_behave_like "accessing and manipulating a has_many :by => :foreign_key association"
178
178
  end
179
-
179
+
180
180
  describe "with :dependent => :destroy option" do
181
181
  define_class(:Book, Document) do
182
182
  has_many :chapters, :by => :foreign_key, :dependent => :destroy
183
183
  end
184
-
184
+
185
185
  subject { Book.create!(:chapters => [chapter1, chapter2, chapter3]) }
186
-
186
+
187
187
  context "when the parent object is destroyed" do
188
188
  it "calls destroy on the child objects" do
189
189
  chapter1.should_receive(:destroy)
190
190
  chapter2.should_receive(:destroy)
191
191
  chapter3.should_receive(:destroy)
192
-
192
+
193
193
  subject.destroy
194
194
  end
195
-
195
+
196
196
  it "removes the child objects from their collection" do
197
197
  subject.destroy
198
-
199
- Chapter.exists?(chapter1.id).should be_false
200
- Chapter.exists?(chapter2.id).should be_false
201
- Chapter.exists?(chapter3.id).should be_false
198
+
199
+ Chapter.exists?(chapter1.id).should be false
200
+ Chapter.exists?(chapter2.id).should be false
201
+ Chapter.exists?(chapter3.id).should be false
202
202
  end
203
203
  end
204
204
  end
205
-
205
+
206
206
  describe "with :dependent => :delete option" do
207
207
  define_class(:Book, Document) do
208
208
  has_many :chapters, :by => :foreign_key, :dependent => :delete
209
209
  end
210
-
210
+
211
211
  subject { Book.create!(:chapters => [chapter1, chapter2, chapter3]) }
212
-
212
+
213
213
  context "when the parent object is destroyed" do
214
214
  it "does not call destroy on the child objects" do
215
215
  chapter1.should_not_receive(:destroy)
216
216
  chapter2.should_not_receive(:destroy)
217
217
  chapter3.should_not_receive(:destroy)
218
-
218
+
219
219
  subject.destroy
220
220
  end
221
-
221
+
222
222
  it "removes the child objects from their collection" do
223
223
  subject.destroy
224
-
225
- Chapter.exists?(chapter1.id).should be_false
226
- Chapter.exists?(chapter2.id).should be_false
227
- Chapter.exists?(chapter3.id).should be_false
224
+
225
+ Chapter.exists?(chapter1.id).should be false
226
+ Chapter.exists?(chapter2.id).should be false
227
+ Chapter.exists?(chapter3.id).should be false
228
228
  end
229
229
  end
230
230
  end
231
231
  end
232
232
  end
233
-
233
+
234
234
  specs_for(EmbeddedDocument) do
235
235
  describe "defining a has_many :by => :foreign_key association" do
236
236
  define_class(:Book, EmbeddedDocument)
237
-
237
+
238
238
  it "raises an exception" do
239
- lambda { Book.has_many :chapters, :by => :foreign_key }.should raise_error
239
+ lambda { Book.has_many :chapters, :by => :foreign_key }.should raise_error(RuntimeError)
240
240
  end
241
241
  end
242
242
  end