dynamoid 0.7.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +2 -24
  3. data/README.markdown +89 -73
  4. data/Rakefile +10 -36
  5. data/dynamoid.gemspec +56 -191
  6. data/lib/dynamoid.rb +6 -4
  7. data/lib/dynamoid/adapter.rb +64 -150
  8. data/lib/dynamoid/adapter_plugin/aws_sdk_v2.rb +579 -0
  9. data/lib/dynamoid/components.rb +0 -1
  10. data/lib/dynamoid/config.rb +2 -5
  11. data/lib/dynamoid/criteria.rb +1 -1
  12. data/lib/dynamoid/criteria/chain.rb +27 -140
  13. data/lib/dynamoid/document.rb +2 -2
  14. data/lib/dynamoid/errors.rb +30 -9
  15. data/lib/dynamoid/fields.rb +15 -3
  16. data/lib/dynamoid/finders.rb +7 -6
  17. data/lib/dynamoid/identity_map.rb +1 -5
  18. data/lib/dynamoid/persistence.rb +108 -93
  19. metadata +56 -229
  20. data/.document +0 -5
  21. data/.rspec +0 -1
  22. data/.travis.yml +0 -7
  23. data/Gemfile.lock +0 -81
  24. data/Gemfile_activemodel4 +0 -24
  25. data/Gemfile_activemodel4.lock +0 -88
  26. data/VERSION +0 -1
  27. data/doc/.nojekyll +0 -0
  28. data/doc/Dynamoid.html +0 -328
  29. data/doc/Dynamoid/Adapter.html +0 -1872
  30. data/doc/Dynamoid/Adapter/AwsSdk.html +0 -2101
  31. data/doc/Dynamoid/Adapter/Local.html +0 -1574
  32. data/doc/Dynamoid/Associations.html +0 -138
  33. data/doc/Dynamoid/Associations/Association.html +0 -847
  34. data/doc/Dynamoid/Associations/BelongsTo.html +0 -161
  35. data/doc/Dynamoid/Associations/ClassMethods.html +0 -766
  36. data/doc/Dynamoid/Associations/HasAndBelongsToMany.html +0 -167
  37. data/doc/Dynamoid/Associations/HasMany.html +0 -167
  38. data/doc/Dynamoid/Associations/HasOne.html +0 -161
  39. data/doc/Dynamoid/Associations/ManyAssociation.html +0 -1684
  40. data/doc/Dynamoid/Associations/SingleAssociation.html +0 -627
  41. data/doc/Dynamoid/Components.html +0 -242
  42. data/doc/Dynamoid/Config.html +0 -412
  43. data/doc/Dynamoid/Config/Options.html +0 -638
  44. data/doc/Dynamoid/Criteria.html +0 -138
  45. data/doc/Dynamoid/Criteria/Chain.html +0 -1471
  46. data/doc/Dynamoid/Criteria/ClassMethods.html +0 -105
  47. data/doc/Dynamoid/Dirty.html +0 -424
  48. data/doc/Dynamoid/Dirty/ClassMethods.html +0 -174
  49. data/doc/Dynamoid/Document.html +0 -1033
  50. data/doc/Dynamoid/Document/ClassMethods.html +0 -1116
  51. data/doc/Dynamoid/Errors.html +0 -125
  52. data/doc/Dynamoid/Errors/ConditionalCheckFailedException.html +0 -141
  53. data/doc/Dynamoid/Errors/DocumentNotValid.html +0 -221
  54. data/doc/Dynamoid/Errors/Error.html +0 -137
  55. data/doc/Dynamoid/Errors/InvalidField.html +0 -141
  56. data/doc/Dynamoid/Errors/InvalidQuery.html +0 -131
  57. data/doc/Dynamoid/Errors/MissingRangeKey.html +0 -141
  58. data/doc/Dynamoid/Fields.html +0 -686
  59. data/doc/Dynamoid/Fields/ClassMethods.html +0 -438
  60. data/doc/Dynamoid/Finders.html +0 -135
  61. data/doc/Dynamoid/Finders/ClassMethods.html +0 -943
  62. data/doc/Dynamoid/IdentityMap.html +0 -492
  63. data/doc/Dynamoid/IdentityMap/ClassMethods.html +0 -534
  64. data/doc/Dynamoid/Indexes.html +0 -321
  65. data/doc/Dynamoid/Indexes/ClassMethods.html +0 -369
  66. data/doc/Dynamoid/Indexes/Index.html +0 -1142
  67. data/doc/Dynamoid/Middleware.html +0 -115
  68. data/doc/Dynamoid/Middleware/IdentityMap.html +0 -264
  69. data/doc/Dynamoid/Persistence.html +0 -892
  70. data/doc/Dynamoid/Persistence/ClassMethods.html +0 -836
  71. data/doc/Dynamoid/Validations.html +0 -415
  72. data/doc/_index.html +0 -506
  73. data/doc/class_list.html +0 -53
  74. data/doc/css/common.css +0 -1
  75. data/doc/css/full_list.css +0 -57
  76. data/doc/css/style.css +0 -338
  77. data/doc/file.LICENSE.html +0 -73
  78. data/doc/file.README.html +0 -416
  79. data/doc/file_list.html +0 -58
  80. data/doc/frames.html +0 -28
  81. data/doc/index.html +0 -416
  82. data/doc/js/app.js +0 -214
  83. data/doc/js/full_list.js +0 -178
  84. data/doc/js/jquery.js +0 -4
  85. data/doc/method_list.html +0 -1144
  86. data/doc/top-level-namespace.html +0 -112
  87. data/lib/dynamoid/adapter/aws_sdk.rb +0 -287
  88. data/lib/dynamoid/indexes.rb +0 -69
  89. data/lib/dynamoid/indexes/index.rb +0 -103
  90. data/spec/app/models/address.rb +0 -13
  91. data/spec/app/models/camel_case.rb +0 -34
  92. data/spec/app/models/car.rb +0 -6
  93. data/spec/app/models/magazine.rb +0 -11
  94. data/spec/app/models/message.rb +0 -9
  95. data/spec/app/models/nuclear_submarine.rb +0 -5
  96. data/spec/app/models/sponsor.rb +0 -8
  97. data/spec/app/models/subscription.rb +0 -12
  98. data/spec/app/models/tweet.rb +0 -12
  99. data/spec/app/models/user.rb +0 -26
  100. data/spec/app/models/vehicle.rb +0 -7
  101. data/spec/dynamoid/adapter/aws_sdk_spec.rb +0 -376
  102. data/spec/dynamoid/adapter_spec.rb +0 -155
  103. data/spec/dynamoid/associations/association_spec.rb +0 -194
  104. data/spec/dynamoid/associations/belongs_to_spec.rb +0 -71
  105. data/spec/dynamoid/associations/has_and_belongs_to_many_spec.rb +0 -47
  106. data/spec/dynamoid/associations/has_many_spec.rb +0 -42
  107. data/spec/dynamoid/associations/has_one_spec.rb +0 -45
  108. data/spec/dynamoid/associations_spec.rb +0 -16
  109. data/spec/dynamoid/config_spec.rb +0 -27
  110. data/spec/dynamoid/criteria/chain_spec.rb +0 -210
  111. data/spec/dynamoid/criteria_spec.rb +0 -75
  112. data/spec/dynamoid/dirty_spec.rb +0 -57
  113. data/spec/dynamoid/document_spec.rb +0 -180
  114. data/spec/dynamoid/fields_spec.rb +0 -156
  115. data/spec/dynamoid/finders_spec.rb +0 -147
  116. data/spec/dynamoid/identity_map_spec.rb +0 -45
  117. data/spec/dynamoid/indexes/index_spec.rb +0 -104
  118. data/spec/dynamoid/indexes_spec.rb +0 -25
  119. data/spec/dynamoid/persistence_spec.rb +0 -301
  120. data/spec/dynamoid/validations_spec.rb +0 -36
  121. data/spec/dynamoid_spec.rb +0 -9
  122. data/spec/spec_helper.rb +0 -55
  123. data/spec/support/with_partitioning.rb +0 -15
@@ -1,45 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
-
3
- describe "Dynamoid::IdentityMap" do
4
- before :each do
5
- Dynamoid::Config.identity_map = true
6
- end
7
-
8
- after :each do
9
- Dynamoid::Config.identity_map = false
10
- end
11
-
12
- context 'object identity' do
13
- it 'maintains a single object' do
14
- tweet = Tweet.create(:tweet_id => "x", :group => "one")
15
- tweet1 = Tweet.where(:tweet_id => "x", :group => "one").first
16
- tweet.should equal(tweet1)
17
- end
18
- end
19
-
20
- context 'cache' do
21
- it 'uses cache' do
22
- tweet = Tweet.create(:tweet_id => "x", :group => "one")
23
- Dynamoid::Adapter.expects(:read).never
24
- tweet1 = Tweet.find_by_id("x", :range_key => "one")
25
- tweet.should equal(tweet1)
26
- end
27
-
28
- it 'clears cache on delete' do
29
- tweet = Tweet.create(:tweet_id => "x", :group => "one")
30
- tweet.delete
31
- Tweet.find_by_id("x", :range_key => "one").should be_nil
32
- end
33
- end
34
-
35
- context 'clear' do
36
- it 'clears the identiy map' do
37
- Tweet.create(:tweet_id => "x", :group => "one")
38
- Tweet.create(:tweet_id => "x", :group => "two")
39
-
40
- Tweet.identity_map.size.should eq(2)
41
- Dynamoid::IdentityMap.clear
42
- Tweet.identity_map.size.should eq(0)
43
- end
44
- end
45
- end
@@ -1,104 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
-
3
- describe "Dynamoid::Indexes::Index" do
4
-
5
- before do
6
- @time = DateTime.now
7
- @index = Dynamoid::Indexes::Index.new(User, [:password, :name], :range_key => :created_at)
8
- end
9
-
10
- it 'reorders keys alphabetically' do
11
- @index.sort([:password, :name, :created_at]).should == [:created_at, :name, :password]
12
- end
13
-
14
- it 'assigns itself hash keys' do
15
- @index.hash_keys.should == [:name, :password]
16
- end
17
-
18
- it 'assigns itself range keys' do
19
- @index.range_keys.should == [:created_at]
20
- end
21
-
22
- it 'reorders its name automatically' do
23
- @index.name.should == [:created_at, :name, :password]
24
- end
25
-
26
- it 'determines its own table name' do
27
- @index.table_name.should == 'dynamoid_tests_index_user_created_ats_and_names_and_passwords'
28
- end
29
-
30
- it 'raises an error if a field does not exist' do
31
- lambda {@index = Dynamoid::Indexes::Index.new(User, [:password, :text])}.should raise_error(Dynamoid::Errors::InvalidField)
32
- end
33
-
34
- it 'returns values for indexes' do
35
- @index.values(:name => 'Josh', :password => 'test123', :created_at => @time).should == {:hash_value => 'Josh.test123', :range_value => @time.to_f}
36
- end
37
-
38
- it 'ignores values for fields that do not exist' do
39
- @index.values(:name => 'Josh', :password => 'test123', :created_at => @time, :email => 'josh@joshsymonds.com').should == {:hash_value => 'Josh.test123', :range_value => @time.to_f}
40
- end
41
-
42
- it 'substitutes a blank string for a hash value that does not exist' do
43
- @index.values(:name => 'Josh', :created_at => @time).should == {:hash_value => 'Josh.', :range_value => @time.to_f}
44
- end
45
-
46
- it 'substitutes a blank string if both hash values do not exist' do
47
- @index.values(:created_at => @time).should == {:hash_value => '.', :range_value => @time.to_f}
48
- end
49
-
50
- it 'accepts values from an object instead of a hash' do
51
- @user = User.new(:name => 'Josh', :password => 'test123', :created_at => @time)
52
-
53
- @index.values(@user).should == {:hash_value => 'Josh.test123', :range_value => @time.to_f}
54
- end
55
-
56
- it 'accepts values from an object and returns changed values' do
57
- @user = User.new(:name => 'Josh', :password => 'test123', :created_at => @time)
58
- @user.name = 'Justin'
59
-
60
- @index.values(@user).should == {:hash_value => 'Justin.test123', :range_value => @time.to_f}
61
- end
62
-
63
- it 'saves an object to the index it is associated with' do
64
- @index = Dynamoid::Indexes::Index.new(User, :name)
65
- @user = User.new(:name => 'Josh', :password => 'test123', :created_at => @time, :id => 'test123')
66
-
67
- @index.save(@user)
68
-
69
- Dynamoid::Adapter.read("dynamoid_tests_index_user_names", 'Josh')[:ids].should == Set['test123']
70
- end
71
-
72
- it 'saves an object to the index it is associated with with a range' do
73
- @index = Dynamoid::Indexes::Index.new(User, :name, :range_key => :last_logged_in_at)
74
- @user = User.create(:name => 'Josh', :last_logged_in_at => @time)
75
-
76
- @index.save(@user)
77
-
78
- Dynamoid::Adapter.read("dynamoid_tests_index_user_last_logged_in_ats_and_names", 'Josh', :range_key => @time.to_f)[:ids].should == Set[@user.id]
79
- end
80
-
81
- it 'deletes an object from the index it is associated with' do
82
- @index = Dynamoid::Indexes::Index.new(User, :name)
83
- @user = User.create(:name => 'Josh', :password => 'test123', :last_logged_in_at => @time, :id => 'test123')
84
-
85
- @index.save(@user)
86
- @index.delete(@user)
87
-
88
- Dynamoid::Adapter.read("dynamoid_tests_index_user_names", 'Josh')[:ids].should be_nil
89
- end
90
-
91
- it 'updates an object by removing it from its previous index and adding it to its new one' do
92
- @index = Dynamoid::Indexes::Index.new(User, :name)
93
- @user = User.create(:name => 'Josh', :password => 'test123', :last_logged_in_at => @time, :id => 'test123')
94
-
95
- Dynamoid::Adapter.read("dynamoid_tests_index_user_names", 'Josh')[:ids].should == Set['test123']
96
- Dynamoid::Adapter.read("dynamoid_tests_index_user_names", 'Justin').should be_nil
97
-
98
- @user.update_attributes(:name => 'Justin')
99
-
100
- Dynamoid::Adapter.read("dynamoid_tests_index_user_names", 'Josh')[:ids].should be_nil
101
- Dynamoid::Adapter.read("dynamoid_tests_index_user_names", 'Justin')[:ids].should == Set['test123']
102
- end
103
-
104
- end
@@ -1,25 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
-
3
- describe "Dynamoid::Indexes" do
4
-
5
- it 'adds indexes to the index array' do
6
- User.indexes.keys.should =~ [[:created_at], [:created_at, :name], [:email], [:email, :name], [:last_logged_in_at, :name], [:name]]
7
- end
8
-
9
- it 'saves indexes to their tables' do
10
- @user = User.new(:name => 'Josh')
11
-
12
- User.indexes.each {|k, v| v.expects(:save).with(@user).once.returns(true)}
13
-
14
- @user.save
15
- end
16
-
17
- it 'deletes indexes when the object is destroyed' do
18
- @user = User.create(:name => 'Josh')
19
-
20
- User.indexes.each {|k, v| v.expects(:delete).with(@user).once.returns(true)}
21
-
22
- @user.destroy
23
- end
24
-
25
- end
@@ -1,301 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
-
3
- describe "Dynamoid::Persistence" do
4
-
5
- before do
6
- Random.stubs(:rand).with(Dynamoid::Config.partition_size).returns(0)
7
- @address = Address.new
8
- end
9
-
10
- context 'without AWS keys' do
11
- unless ENV['ACCESS_KEY'] && ENV['SECRET_KEY']
12
- before do
13
- Dynamoid::Adapter.delete_table(Address.table_name) if Dynamoid::Adapter.list_tables.include?(Address.table_name)
14
- end
15
-
16
- it 'creates a table' do
17
- Address.create_table(:table_name => Address.table_name)
18
-
19
- Dynamoid::Adapter.list_tables.should include 'dynamoid_tests_addresses'
20
- end
21
-
22
- it 'checks if a table already exists' do
23
- Address.create_table(:table_name => Address.table_name)
24
-
25
- Address.table_exists?(Address.table_name).should be_true
26
- Address.table_exists?('crazytable').should be_false
27
- end
28
- end
29
- end
30
-
31
- it 'assigns itself an id on save' do
32
- @address.save
33
-
34
- Dynamoid::Adapter.read("dynamoid_tests_addresses", @address.id)[:id].should == @address.id
35
- end
36
-
37
- it 'prevents concurrent writes to tables with a lock_version' do
38
- @address.save!
39
- a1 = @address
40
- a2 = Address.find(@address.id)
41
-
42
- a1.city = 'Seattle'
43
- a2.city = 'San Francisco'
44
-
45
- a1.save!
46
- expect { a2.save! }.to raise_exception(Dynamoid::Errors::ConditionalCheckFailedException)
47
- end
48
-
49
- configured_with 'partitioning' do
50
- it 'raises an error when attempting to use optimistic locking' do
51
- expect { address.save! }.to raise_exception
52
- end
53
- end
54
-
55
- it 'assigns itself an id on save only if it does not have one' do
56
- @address.id = 'test123'
57
- @address.save
58
-
59
- Dynamoid::Adapter.read("dynamoid_tests_addresses", 'test123').should_not be_empty
60
- end
61
-
62
- it 'has a table name' do
63
- Address.table_name.should == 'dynamoid_tests_addresses'
64
- end
65
-
66
- it 'saves indexes along with itself' do
67
- @user = User.new(:name => 'Josh')
68
-
69
- @user.expects(:save_indexes).once.returns(true)
70
- @user.save
71
- end
72
-
73
- it 'deletes an item completely' do
74
- @user = User.create(:name => 'Josh')
75
- @user.destroy
76
-
77
- Dynamoid::Adapter.read("dynamoid_tests_users", @user.id).should be_nil
78
- end
79
-
80
- it 'keeps string attributes as strings' do
81
- @user = User.new(:name => 'Josh')
82
- @user.send(:dump)[:name].should == 'Josh'
83
- end
84
-
85
- it 'dumps datetime attributes' do
86
- @user = User.create(:name => 'Josh')
87
- @user.send(:dump)[:name].should == 'Josh'
88
- end
89
-
90
- it 'dumps integer attributes' do
91
- @subscription = Subscription.create(:length => 10)
92
- @subscription.send(:dump)[:length].should == 10
93
- end
94
-
95
- it 'dumps set attributes' do
96
- @subscription = Subscription.create(:length => 10)
97
- @magazine = @subscription.magazine.create
98
-
99
- @subscription.send(:dump)[:magazine_ids].should == Set[@magazine.id]
100
- end
101
-
102
- it 'handles nil attributes properly' do
103
- Address.undump(nil).should be_a(Hash)
104
- end
105
-
106
- it 'dumps and undump a serialized field' do
107
- @address.options = (hash = {:x => [1, 2], "foobar" => 3.14})
108
- Address.undump(@address.send(:dump))[:options].should == hash
109
- end
110
-
111
- [true, false].each do |bool|
112
- it "dumps a #{bool} boolean field" do
113
- @address.deliverable = bool
114
- Address.undump(@address.send(:dump))[:deliverable].should == bool
115
- end
116
- end
117
-
118
- it 'raises on an invalid boolean value' do
119
- expect do
120
- @address.deliverable = true
121
- data = @address.send(:dump)
122
- data[:deliverable] = 'foo'
123
- Address.undump(data)
124
- end.to raise_error(ArgumentError)
125
- end
126
-
127
- it 'loads a hash into a serialized field' do
128
- hash = {foo: :bar}
129
- Address.new(options: hash).options.should == hash
130
- end
131
-
132
- it 'loads attributes from a hash' do
133
- @time = DateTime.now
134
- @hash = {:name => 'Josh', :created_at => @time.to_f}
135
-
136
- User.undump(@hash)[:name].should == 'Josh'
137
- User.undump(@hash)[:created_at].to_f == @time.to_f
138
- end
139
-
140
- it 'runs the before_create callback only once' do
141
- CamelCase.any_instance.expects(:doing_before_create).once.returns(true)
142
-
143
- CamelCase.create
144
- end
145
-
146
- it 'runs after save callbacks when doing #create' do
147
- CamelCase.any_instance.expects(:doing_after_create).once.returns(true)
148
-
149
- CamelCase.create
150
- end
151
-
152
- it 'runs after save callbacks when doing #save' do
153
- CamelCase.any_instance.expects(:doing_after_create).once.returns(true)
154
-
155
- CamelCase.new.save
156
- end
157
-
158
- it 'works with a HashWithIndifferentAccess' do
159
- hash = ActiveSupport::HashWithIndifferentAccess.new("city" => "Atlanta")
160
-
161
- lambda {Address.create(hash)}.should_not raise_error
162
- end
163
-
164
- context 'create' do
165
- {
166
- Tweet => ['with range', { :tweet_id => 1, :group => 'abc' }],
167
- Message => ['without range', { :message_id => 1, :text => 'foo', :time => DateTime.now }]
168
- }.each_pair do |clazz, fields|
169
- it "checks for existence of an existing object #{fields[0]}" do
170
- t1 = clazz.new(fields[1])
171
- t2 = clazz.new(fields[1])
172
-
173
- t1.save
174
- expect do
175
- t2.save!
176
- end.to raise_exception Dynamoid::Errors::ConditionalCheckFailedException
177
- end
178
- end
179
- end
180
-
181
- context 'unknown fields' do
182
- let(:clazz) do
183
- Class.new do
184
- include Dynamoid::Document
185
- table :name => :addresses
186
-
187
- field :city
188
- field :options, :serialized
189
- field :deliverable, :bad_type_specifier
190
- end
191
- end
192
-
193
- it 'raises when undumping a column with an unknown field type' do
194
- expect do
195
- clazz.new(:deliverable => true) #undump is called here
196
- end.to raise_error(ArgumentError)
197
- end
198
-
199
- it 'raises when dumping a column with an unknown field type' do
200
- doc = clazz.new
201
- doc.deliverable = true
202
- expect do
203
- doc.dump
204
- end.to raise_error(ArgumentError)
205
- end
206
- end
207
-
208
- context 'update' do
209
-
210
- before :each do
211
- @tweet = Tweet.create(:tweet_id => 1, :group => 'abc', :count => 5, :tags => ['db', 'sql'], :user_name => 'john')
212
- end
213
-
214
- it 'runs before_update callbacks when doing #update' do
215
- CamelCase.any_instance.expects(:doing_before_update).once.returns(true)
216
-
217
- CamelCase.create(:color => 'blue').update do |t|
218
- t.set(:color => 'red')
219
- end
220
- end
221
-
222
- it 'runs after_update callbacks when doing #update' do
223
- CamelCase.any_instance.expects(:doing_after_update).once.returns(true)
224
-
225
- CamelCase.create(:color => 'blue').update do |t|
226
- t.set(:color => 'red')
227
- end
228
- end
229
-
230
- it 'support add/delete operation on a field' do
231
- @tweet.update do |t|
232
- t.add(:count => 3)
233
- t.delete(:tags => ['db'])
234
- end
235
-
236
- @tweet.count.should eq(8)
237
- @tweet.tags.to_a.should eq(['sql'])
238
- end
239
-
240
- it 'checks the conditions on update' do
241
- @tweet.update(:if => { :count => 5 }) do |t|
242
- t.add(:count => 3)
243
- end.should be_true
244
-
245
- @tweet.count.should eq(8)
246
-
247
- @tweet.update(:if => { :count => 5 }) do |t|
248
- t.add(:count => 3)
249
- end.should be_false
250
-
251
- @tweet.count.should eq(8)
252
-
253
- expect {
254
- @tweet.update!(:if => { :count => 5 }) do |t|
255
- t.add(:count => 3)
256
- end
257
- }.to raise_error(Dynamoid::Errors::ConditionalCheckFailedException)
258
- end
259
-
260
- it 'prevents concurrent saves to tables with a lock_version' do
261
- @address.save!
262
- a2 = Address.find(@address.id)
263
- a2.update! { |a| a.set(:city => "Chicago") }
264
-
265
- expect do
266
- @address.city = "Seattle"
267
- @address.save!
268
- end.to raise_error(Dynamoid::Errors::ConditionalCheckFailedException)
269
- end
270
-
271
- end
272
-
273
- context 'delete' do
274
- it 'deletes model with datetime range key' do
275
- lambda {
276
- msg = Message.create!(:message_id => 1, :time => DateTime.now, :text => "Hell yeah")
277
- msg.destroy
278
- }.should_not raise_error
279
- end
280
- end
281
-
282
- context 'single table inheritance' do
283
- let(:car) { Car.create(power_locks: false) }
284
- let(:sub) { NuclearSubmarine.create(torpedoes: 5) }
285
-
286
- it 'saves subclass objects in the parent table' do
287
- c = car
288
- Vehicle.find(c.id).should == c
289
- end
290
-
291
- it 'loads subclass item when querying the parent table' do
292
- c = car
293
- s = sub
294
-
295
- Vehicle.all.to_a.tap { |v|
296
- v.should include(c)
297
- v.should include(s)
298
- }
299
- end
300
- end
301
- end