massive_record 0.2.1 → 0.2.2.rc1
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.
- data/CHANGELOG.md +58 -2
- data/Gemfile.lock +17 -17
- data/README.md +98 -41
- data/lib/massive_record.rb +2 -1
- data/lib/massive_record/adapters/thrift/hbase/hbase.rb +2425 -2154
- data/lib/massive_record/adapters/thrift/hbase/hbase_constants.rb +3 -3
- data/lib/massive_record/adapters/thrift/hbase/hbase_types.rb +195 -195
- data/lib/massive_record/adapters/thrift/row.rb +35 -4
- data/lib/massive_record/adapters/thrift/table.rb +49 -12
- data/lib/massive_record/orm/attribute_methods.rb +77 -5
- data/lib/massive_record/orm/attribute_methods/cast_numbers_on_write.rb +24 -0
- data/lib/massive_record/orm/attribute_methods/dirty.rb +18 -0
- data/lib/massive_record/orm/attribute_methods/time_zone_conversion.rb +24 -3
- data/lib/massive_record/orm/attribute_methods/write.rb +8 -1
- data/lib/massive_record/orm/base.rb +62 -8
- data/lib/massive_record/orm/column.rb +7 -11
- data/lib/massive_record/orm/default_id.rb +1 -1
- data/lib/massive_record/orm/embedded.rb +66 -0
- data/lib/massive_record/orm/errors.rb +17 -0
- data/lib/massive_record/orm/finders.rb +124 -71
- data/lib/massive_record/orm/finders/rescue_missing_table_on_find.rb +1 -1
- data/lib/massive_record/orm/finders/scope.rb +58 -34
- data/lib/massive_record/orm/id_factory.rb +22 -105
- data/lib/massive_record/orm/id_factory/atomic_incrementation.rb +117 -0
- data/lib/massive_record/orm/id_factory/timestamp.rb +60 -0
- data/lib/massive_record/orm/identity_map.rb +256 -0
- data/lib/massive_record/orm/log_subscriber.rb +18 -0
- data/lib/massive_record/orm/observer.rb +69 -0
- data/lib/massive_record/orm/persistence.rb +47 -119
- data/lib/massive_record/orm/persistence/operations.rb +100 -0
- data/lib/massive_record/orm/persistence/operations/atomic_operation.rb +71 -0
- data/lib/massive_record/orm/persistence/operations/destroy.rb +17 -0
- data/lib/massive_record/orm/persistence/operations/embedded/destroy.rb +26 -0
- data/lib/massive_record/orm/persistence/operations/embedded/insert.rb +27 -0
- data/lib/massive_record/orm/persistence/operations/embedded/operation_helpers.rb +66 -0
- data/lib/massive_record/orm/persistence/operations/embedded/reload.rb +39 -0
- data/lib/massive_record/orm/persistence/operations/embedded/update.rb +29 -0
- data/lib/massive_record/orm/persistence/operations/insert.rb +19 -0
- data/lib/massive_record/orm/persistence/operations/reload.rb +26 -0
- data/lib/massive_record/orm/persistence/operations/suppress.rb +15 -0
- data/lib/massive_record/orm/persistence/operations/table_operation_helpers.rb +106 -0
- data/lib/massive_record/orm/persistence/operations/update.rb +25 -0
- data/lib/massive_record/orm/query_instrumentation.rb +26 -49
- data/lib/massive_record/orm/raw_data.rb +47 -0
- data/lib/massive_record/orm/relations.rb +4 -0
- data/lib/massive_record/orm/relations/interface.rb +134 -0
- data/lib/massive_record/orm/relations/metadata.rb +58 -12
- data/lib/massive_record/orm/relations/proxy.rb +17 -12
- data/lib/massive_record/orm/relations/proxy/embedded_in.rb +54 -0
- data/lib/massive_record/orm/relations/proxy/embedded_in_polymorphic.rb +15 -0
- data/lib/massive_record/orm/relations/proxy/embeds_many.rb +215 -0
- data/lib/massive_record/orm/relations/proxy/references_many.rb +112 -88
- data/lib/massive_record/orm/relations/proxy/references_one.rb +1 -1
- data/lib/massive_record/orm/relations/proxy/references_one_polymorphic.rb +1 -1
- data/lib/massive_record/orm/relations/proxy_collection.rb +84 -0
- data/lib/massive_record/orm/schema/column_family.rb +3 -2
- data/lib/massive_record/orm/schema/{column_interface.rb → embedded_interface.rb} +38 -4
- data/lib/massive_record/orm/schema/field.rb +2 -0
- data/lib/massive_record/orm/schema/table_interface.rb +19 -2
- data/lib/massive_record/orm/single_table_inheritance.rb +37 -2
- data/lib/massive_record/orm/timestamps.rb +17 -7
- data/lib/massive_record/orm/validations.rb +4 -0
- data/lib/massive_record/orm/validations/associated.rb +50 -0
- data/lib/massive_record/rails/railtie.rb +31 -0
- data/lib/massive_record/version.rb +1 -1
- data/lib/massive_record/wrapper/cell.rb +8 -1
- data/massive_record.gemspec +4 -4
- data/spec/adapter/thrift/atomic_increment_spec.rb +16 -0
- data/spec/adapter/thrift/table_find_spec.rb +14 -2
- data/spec/adapter/thrift/table_spec.rb +6 -6
- data/spec/adapter/thrift/utf8_encoding_of_id_spec.rb +71 -0
- data/spec/orm/cases/attribute_methods_spec.rb +215 -22
- data/spec/orm/cases/auto_generate_id_spec.rb +1 -1
- data/spec/orm/cases/change_id_spec.rb +62 -0
- data/spec/orm/cases/default_id_spec.rb +25 -6
- data/spec/orm/cases/default_values_spec.rb +6 -3
- data/spec/orm/cases/dirty_spec.rb +150 -102
- data/spec/orm/cases/embedded_spec.rb +250 -0
- data/spec/orm/cases/{finder_default_scope.rb → finder_default_scope_spec.rb} +4 -0
- data/spec/orm/cases/finder_scope_spec.rb +96 -29
- data/spec/orm/cases/finders_spec.rb +57 -10
- data/spec/orm/cases/id_factory/atomic_incrementation_spec.rb +72 -0
- data/spec/orm/cases/id_factory/timestamp_spec.rb +61 -0
- data/spec/orm/cases/identity_map/identity_map_spec.rb +357 -0
- data/spec/orm/cases/identity_map/middleware_spec.rb +74 -0
- data/spec/orm/cases/log_subscriber_spec.rb +15 -2
- data/spec/orm/cases/observing_spec.rb +61 -0
- data/spec/orm/cases/persistence_spec.rb +151 -60
- data/spec/orm/cases/raw_data_spec.rb +58 -0
- data/spec/orm/cases/single_table_inheritance_spec.rb +58 -2
- data/spec/orm/cases/table_spec.rb +3 -3
- data/spec/orm/cases/time_zone_awareness_spec.rb +27 -0
- data/spec/orm/cases/timestamps_spec.rb +23 -109
- data/spec/orm/cases/validation_spec.rb +9 -0
- data/spec/orm/models/address.rb +5 -1
- data/spec/orm/models/address_with_timestamp.rb +12 -0
- data/spec/orm/models/car.rb +5 -0
- data/spec/orm/models/person.rb +13 -1
- data/spec/orm/models/person_with_timestamp.rb +4 -2
- data/spec/orm/models/test_class.rb +1 -0
- data/spec/orm/persistence/operations/atomic_operation_spec.rb +58 -0
- data/spec/orm/persistence/operations/destroy_spec.rb +22 -0
- data/spec/orm/persistence/operations/embedded/destroy_spec.rb +71 -0
- data/spec/orm/persistence/operations/embedded/insert_spec.rb +59 -0
- data/spec/orm/persistence/operations/embedded/operation_helpers_spec.rb +92 -0
- data/spec/orm/persistence/operations/embedded/reload_spec.rb +67 -0
- data/spec/orm/persistence/operations/embedded/update_spec.rb +60 -0
- data/spec/orm/persistence/operations/insert_spec.rb +31 -0
- data/spec/orm/persistence/operations/reload_spec.rb +48 -0
- data/spec/orm/persistence/operations/suppress_spec.rb +17 -0
- data/spec/orm/persistence/operations/table_operation_helpers_spec.rb +98 -0
- data/spec/orm/persistence/operations/update_spec.rb +25 -0
- data/spec/orm/persistence/operations_spec.rb +58 -0
- data/spec/orm/relations/interface_spec.rb +188 -0
- data/spec/orm/relations/metadata_spec.rb +92 -15
- data/spec/orm/relations/proxy/embedded_in_polymorphic_spec.rb +37 -0
- data/spec/orm/relations/proxy/embedded_in_spec.rb +66 -0
- data/spec/orm/relations/proxy/embeds_many_spec.rb +651 -0
- data/spec/orm/relations/proxy/references_many_spec.rb +466 -2
- data/spec/orm/schema/column_family_spec.rb +21 -0
- data/spec/orm/schema/embedded_interface_spec.rb +181 -0
- data/spec/orm/schema/field_spec.rb +7 -0
- data/spec/orm/schema/table_interface_spec.rb +31 -1
- data/spec/shared/orm/id_factories.rb +44 -0
- data/spec/shared/orm/model_with_timestamps.rb +132 -0
- data/spec/shared/orm/persistence/a_persistence_embedded_operation_class.rb +3 -0
- data/spec/shared/orm/persistence/a_persistence_operation_class.rb +11 -0
- data/spec/shared/orm/persistence/a_persistence_table_operation_class.rb +11 -0
- data/spec/shared/orm/relations/proxy.rb +9 -2
- data/spec/spec_helper.rb +9 -0
- data/spec/support/mock_massive_record_connection.rb +2 -1
- metadata +106 -21
- data/spec/orm/cases/column_spec.rb +0 -49
- data/spec/orm/cases/id_factory_spec.rb +0 -92
- data/spec/orm/schema/column_interface_spec.rb +0 -136
@@ -105,6 +105,165 @@ describe TestReferencesManyProxy do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
|
108
|
+
describe "#find_in_batches" do
|
109
|
+
context "when the proxy is loaded" do
|
110
|
+
before do
|
111
|
+
proxy_owner.save!
|
112
|
+
proxy_owner.test_classes.concat(proxy_target, proxy_target_2, proxy_target_3)
|
113
|
+
end
|
114
|
+
|
115
|
+
it "returns records in batches of given size" do
|
116
|
+
result = []
|
117
|
+
|
118
|
+
subject.find_in_batches(:batch_size => 1) do |records_batch|
|
119
|
+
result << records_batch
|
120
|
+
end
|
121
|
+
|
122
|
+
result.should eq [[proxy_target], [proxy_target_2], [proxy_target_3]]
|
123
|
+
end
|
124
|
+
|
125
|
+
it "filters when given :starts_with" do
|
126
|
+
proxy_target_3_3 = TestClass.new("test-class-id-3-1")
|
127
|
+
proxy_owner.test_classes << proxy_target_3_3
|
128
|
+
|
129
|
+
result = []
|
130
|
+
|
131
|
+
subject.find_in_batches(:batch_size => 1, :starts_with => "test-class-id-3") do |records_batch|
|
132
|
+
result << records_batch
|
133
|
+
end
|
134
|
+
|
135
|
+
result.should eq [[proxy_target_3], [proxy_target_3_3]]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "when persisted foreign keys" do
|
140
|
+
before do
|
141
|
+
proxy_owner.save!
|
142
|
+
proxy_owner.test_classes.concat(proxy_target, proxy_target_2, proxy_target_3)
|
143
|
+
subject.reset
|
144
|
+
end
|
145
|
+
|
146
|
+
it "returns records in batches of given size" do
|
147
|
+
result = []
|
148
|
+
|
149
|
+
subject.find_in_batches(:batch_size => 1) do |records_batch|
|
150
|
+
result << records_batch
|
151
|
+
end
|
152
|
+
|
153
|
+
result.should eq [[proxy_target], [proxy_target_2], [proxy_target_3]]
|
154
|
+
end
|
155
|
+
|
156
|
+
it "filters when given :starts_with" do
|
157
|
+
proxy_target_3_3 = TestClass.new("test-class-id-3-1")
|
158
|
+
proxy_owner.test_classes << proxy_target_3_3
|
159
|
+
subject.reset
|
160
|
+
|
161
|
+
result = []
|
162
|
+
|
163
|
+
subject.find_in_batches(:batch_size => 1, :starts_with => "test-class-id-3") do |records_batch|
|
164
|
+
result << records_batch
|
165
|
+
end
|
166
|
+
|
167
|
+
result.should eq [[proxy_target_3], [proxy_target_3_3]]
|
168
|
+
end
|
169
|
+
|
170
|
+
it "does not alter foreign keys in proxy owner" do
|
171
|
+
foreign_keys_before_batches = proxy_owner.test_class_ids.dup
|
172
|
+
|
173
|
+
subject.find_in_batches(:batch_size => 1, :starts_with => "test-class-id-3") do |records_batch|
|
174
|
+
end
|
175
|
+
|
176
|
+
proxy_owner.test_class_ids.should eq foreign_keys_before_batches
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
context "when finding with a given start id" do
|
181
|
+
(1..6).each do |i|
|
182
|
+
let("record_#{i}") { TestClass.create! "test-#{i}" }
|
183
|
+
end
|
184
|
+
|
185
|
+
let(:records) { (1..6).collect { |i| send("record_#{i}") } }
|
186
|
+
|
187
|
+
before do
|
188
|
+
records # touch to save
|
189
|
+
|
190
|
+
subject.metadata.records_starts_from = :test_classes_starts_from
|
191
|
+
subject.proxy_owner.should_receive(:test_classes_starts_from).and_return("test-")
|
192
|
+
end
|
193
|
+
|
194
|
+
after { subject.metadata.records_starts_from = nil }
|
195
|
+
|
196
|
+
|
197
|
+
it "returns records in one batch" do
|
198
|
+
result = []
|
199
|
+
|
200
|
+
subject.find_in_batches(:batch_size => 10) do |records_batch|
|
201
|
+
result << records_batch
|
202
|
+
end
|
203
|
+
|
204
|
+
result.should eq [records]
|
205
|
+
end
|
206
|
+
|
207
|
+
it "returns records in one batch" do
|
208
|
+
result = []
|
209
|
+
|
210
|
+
subject.find_in_batches(:batch_size => 3) do |records_batch|
|
211
|
+
result << records_batch
|
212
|
+
end
|
213
|
+
|
214
|
+
result.should eq [records.slice(0, 3), records.slice(3, 3)]
|
215
|
+
end
|
216
|
+
|
217
|
+
describe "an overridden start id" do
|
218
|
+
(11..16).each do |i|
|
219
|
+
let("record_#{i}") { TestClass.create! "test-1-#{i}" }
|
220
|
+
end
|
221
|
+
|
222
|
+
let(:records_above_10) { (11..16).collect { |i| send("record_#{i}") } }
|
223
|
+
|
224
|
+
before { records_above_10 }
|
225
|
+
|
226
|
+
it "returns only records with given start" do
|
227
|
+
result = []
|
228
|
+
|
229
|
+
subject.find_in_batches(:batch_size => 3, :starts_with => "test-1-") do |records_batch|
|
230
|
+
result << records_batch
|
231
|
+
end
|
232
|
+
|
233
|
+
result.should eq [records_above_10.slice(0, 3), records_above_10.slice(3, 3)]
|
234
|
+
end
|
235
|
+
|
236
|
+
it "raises an error if your start option starst with some incorrect value" do
|
237
|
+
expect {
|
238
|
+
subject.find_in_batches(:starts_with => 'incorrect_value') { |b| }
|
239
|
+
}.to raise_error MassiveRecord::ORM::Relations::InvalidStartsWithOption
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
|
246
|
+
describe "#find_each" do
|
247
|
+
it "delegate to find_in_batches" do
|
248
|
+
subject.should_receive(:find_in_batches).with(:batch_size => 2, :starts_with => :from_here)
|
249
|
+
subject.find_each(:batch_size => 2, :starts_with => :from_here)
|
250
|
+
end
|
251
|
+
|
252
|
+
it "yields one and one record" do
|
253
|
+
proxy_owner.save!
|
254
|
+
proxy_owner.test_classes.concat(proxy_target, proxy_target_2, proxy_target_3)
|
255
|
+
|
256
|
+
result = []
|
257
|
+
|
258
|
+
subject.find_each do |record|
|
259
|
+
result << record
|
260
|
+
end
|
261
|
+
|
262
|
+
result.should eq [proxy_target, proxy_target_2, proxy_target_3]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
|
108
267
|
describe "adding records to collection" do
|
109
268
|
[:<<, :push, :concat].each do |add_method|
|
110
269
|
describe "by ##{add_method}" do
|
@@ -138,7 +297,7 @@ describe TestReferencesManyProxy do
|
|
138
297
|
end
|
139
298
|
|
140
299
|
it "should not update array of foreign keys in proxy_owner if it does not respond to it" do
|
141
|
-
proxy_owner.should_receive(:respond_to?).
|
300
|
+
proxy_owner.should_receive(:respond_to?).and_return(false)
|
142
301
|
subject.send(add_method, proxy_target)
|
143
302
|
proxy_owner.test_class_ids.should_not include(proxy_target.id)
|
144
303
|
end
|
@@ -296,6 +455,11 @@ describe TestReferencesManyProxy do
|
|
296
455
|
proxy_target_2.should_receive(:destroy)
|
297
456
|
subject.destroy_all
|
298
457
|
end
|
458
|
+
|
459
|
+
it "returns destroyed records" do
|
460
|
+
removed = subject.destroy_all
|
461
|
+
removed.should include proxy_target, proxy_target_2
|
462
|
+
end
|
299
463
|
end
|
300
464
|
|
301
465
|
describe "with delete_all" do
|
@@ -329,6 +493,11 @@ describe TestReferencesManyProxy do
|
|
329
493
|
proxy_target_2.should_not_receive(:destroy)
|
330
494
|
subject.delete_all
|
331
495
|
end
|
496
|
+
|
497
|
+
it "returns deleted records" do
|
498
|
+
removed = subject.delete_all
|
499
|
+
removed.should include proxy_target, proxy_target_2
|
500
|
+
end
|
332
501
|
end
|
333
502
|
end
|
334
503
|
|
@@ -361,12 +530,182 @@ describe TestReferencesManyProxy do
|
|
361
530
|
subject << proxy_target_2
|
362
531
|
subject.send(method).should == 2
|
363
532
|
end
|
533
|
+
|
534
|
+
it "returns correct length if new proxy gets records added" do
|
535
|
+
subject.destroy_all
|
536
|
+
subject.reset
|
537
|
+
proxy_owner.stub(:persisted?).and_return false
|
538
|
+
proxy_owner.stub(:new_record?).and_return true
|
539
|
+
|
540
|
+
new_proxy_target = proxy_target.class.new "id-1"
|
541
|
+
subject << new_proxy_target
|
542
|
+
subject.length.should eq 1
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
|
547
|
+
context "foreign keys persisted in owner" do
|
548
|
+
before do
|
549
|
+
proxy_owner.save!
|
550
|
+
subject << proxy_target << proxy_target_2
|
551
|
+
end
|
552
|
+
|
553
|
+
context "targets not loaded" do
|
554
|
+
before { subject.reset }
|
555
|
+
|
556
|
+
it "loads nothing" do
|
557
|
+
TestClass.should_not_receive(:find)
|
558
|
+
subject.length
|
559
|
+
end
|
560
|
+
|
561
|
+
it "reads length from proxy owner's foreign keys list" do
|
562
|
+
proxy_owner.should_receive(:test_class_ids).and_return([proxy_target.id, proxy_target_2.id])
|
563
|
+
subject.length
|
564
|
+
end
|
565
|
+
|
566
|
+
it "returns correct length" do
|
567
|
+
subject.length.should eq 2
|
568
|
+
end
|
569
|
+
end
|
570
|
+
|
571
|
+
context "targets loaded" do
|
572
|
+
before { subject.reload }
|
573
|
+
|
574
|
+
it "loads nothing" do
|
575
|
+
TestClass.should_not_receive(:find)
|
576
|
+
subject.length
|
577
|
+
end
|
578
|
+
|
579
|
+
it "reads length from proxy_target" do
|
580
|
+
subject.should_receive(:proxy_target).and_return([proxy_target, proxy_target_2])
|
581
|
+
subject.length
|
582
|
+
end
|
583
|
+
|
584
|
+
it "returns correct length" do
|
585
|
+
subject.length.should eq 2
|
586
|
+
end
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
context "when we are using a starts_with to find related records" do
|
591
|
+
let(:proxy_target) { Person.new proxy_owner.id+"-friend-1", :name => "T", :age => 2 }
|
592
|
+
let(:proxy_target_2) { Person.new proxy_owner.id+"-friend-2", :name => "H", :age => 9 }
|
593
|
+
let(:not_proxy_target) { Person.new "foo"+"-friend-2", :name => "H", :age => 1 }
|
594
|
+
let(:metadata) { subject.metadata }
|
595
|
+
|
596
|
+
subject { proxy_owner.send(:relation_proxy, 'friends') }
|
597
|
+
|
598
|
+
before do
|
599
|
+
proxy_owner.save!
|
600
|
+
subject << proxy_target << proxy_target_2
|
601
|
+
end
|
602
|
+
|
603
|
+
context "targets not loaded" do
|
604
|
+
before { subject.reset }
|
605
|
+
|
606
|
+
it "loads all the targets and returns it's length" do
|
607
|
+
subject.should_receive(:load_proxy_target).and_return [proxy_target, proxy_target_2]
|
608
|
+
subject.length
|
609
|
+
end
|
610
|
+
|
611
|
+
it "returns correct length" do
|
612
|
+
subject.length.should eq 2
|
613
|
+
end
|
614
|
+
|
615
|
+
it "returns correct length after adding a record" do
|
616
|
+
subject << Person.new(proxy_owner.id+"-friend-3", :name => "H", :age => 9)
|
617
|
+
subject.length.should eq 3
|
618
|
+
end
|
619
|
+
end
|
620
|
+
|
621
|
+
context "targets loaded" do
|
622
|
+
before { subject.reload }
|
623
|
+
|
624
|
+
it "loads nothing" do
|
625
|
+
subject.should_not_receive(:load_proxy_target)
|
626
|
+
subject.length
|
627
|
+
end
|
628
|
+
|
629
|
+
it "returns correct length" do
|
630
|
+
subject.length.should eq 2
|
631
|
+
end
|
364
632
|
end
|
365
633
|
end
|
366
634
|
end
|
367
635
|
end
|
368
636
|
|
369
|
-
describe "#
|
637
|
+
describe "#any?" do
|
638
|
+
before { subject.reset }
|
639
|
+
|
640
|
+
it "checks the length and return true if it is greater than 0" do
|
641
|
+
subject.should_receive(:length).and_return 1
|
642
|
+
subject.any?.should be_true
|
643
|
+
end
|
644
|
+
|
645
|
+
it "checks the length and return false if it is 0" do
|
646
|
+
subject.should_receive(:length).and_return 0
|
647
|
+
subject.any?.should be_false
|
648
|
+
end
|
649
|
+
|
650
|
+
context "when find with proc" do
|
651
|
+
before do
|
652
|
+
subject.should_receive(:loaded?).and_return false
|
653
|
+
subject.should_receive(:find_with_proc?).and_return true
|
654
|
+
end
|
655
|
+
|
656
|
+
it "asks for first and returns false if first is nil" do
|
657
|
+
subject.should_receive(:first).and_return nil
|
658
|
+
subject.any?.should be_false
|
659
|
+
end
|
660
|
+
|
661
|
+
it "asks for first and returns true if first is a record" do
|
662
|
+
subject.should_receive(:first).and_return proxy_target
|
663
|
+
subject.any?.should be_true
|
664
|
+
end
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
describe "#present?" do
|
669
|
+
before { subject.reset }
|
670
|
+
|
671
|
+
it "checks the length and return true if it is greater than 0" do
|
672
|
+
subject.should_receive(:length).and_return 1
|
673
|
+
subject.present?.should be_true
|
674
|
+
end
|
675
|
+
|
676
|
+
it "checks the length and return false if it is 0" do
|
677
|
+
subject.should_receive(:length).and_return 0
|
678
|
+
subject.present?.should be_false
|
679
|
+
end
|
680
|
+
end
|
681
|
+
|
682
|
+
describe "#include?" do
|
683
|
+
it "uses find as it's query method when loaded" do
|
684
|
+
subject.should_receive(:loaded?).and_return true
|
685
|
+
subject.should_receive(:find).with(proxy_target.id).and_return true
|
686
|
+
subject.should include proxy_target
|
687
|
+
end
|
688
|
+
|
689
|
+
it "uses find as it's query method when find with proc" do
|
690
|
+
subject.should_receive(:find_with_proc?).and_return true
|
691
|
+
subject.should_receive(:find).with(proxy_target.id).and_return true
|
692
|
+
subject.should include proxy_target
|
693
|
+
end
|
694
|
+
|
695
|
+
it "can answer to ids as well" do
|
696
|
+
subject.should_receive(:foreign_key_in_proxy_owner_exists?).with(proxy_target.id).and_return true
|
697
|
+
subject.should include proxy_target.id
|
698
|
+
end
|
699
|
+
|
700
|
+
it "does not load record if foreign keys are presisted in proxy owner" do
|
701
|
+
proxy_owner.save!
|
702
|
+
subject << proxy_target
|
703
|
+
subject.reset
|
704
|
+
|
705
|
+
TestClass.should_not_receive(:find)
|
706
|
+
subject.should include proxy_target
|
707
|
+
end
|
708
|
+
|
370
709
|
[true, false].each do |should_persist_proxy_owner|
|
371
710
|
describe "with proxy_owner " + (should_persist_proxy_owner ? "persisted" : "not persisted") do
|
372
711
|
before do
|
@@ -521,6 +860,17 @@ describe TestReferencesManyProxy do
|
|
521
860
|
lambda { subject.find(not_among_targets.id) }.should raise_error MassiveRecord::ORM::RecordNotFound
|
522
861
|
end
|
523
862
|
|
863
|
+
it "returns record if in a dirty state, when no objects are saved" do
|
864
|
+
subject.destroy_all
|
865
|
+
subject.reset
|
866
|
+
proxy_owner.stub(:persisted?).and_return false
|
867
|
+
proxy_owner.stub(:new_record?).and_return true
|
868
|
+
|
869
|
+
new_proxy_target = Person.new proxy_owner.id+"-friend-2", :name => "H", :age => 9
|
870
|
+
subject << new_proxy_target
|
871
|
+
subject.find(new_proxy_target.id).should eq new_proxy_target
|
872
|
+
end
|
873
|
+
|
524
874
|
|
525
875
|
|
526
876
|
it "should not hit database if proxy has been loaded" do
|
@@ -536,6 +886,94 @@ describe TestReferencesManyProxy do
|
|
536
886
|
end
|
537
887
|
end
|
538
888
|
|
889
|
+
describe "#all" do
|
890
|
+
let(:not_among_targets) { proxy_target_3 }
|
891
|
+
|
892
|
+
describe "stored foreign keys" do
|
893
|
+
before do
|
894
|
+
proxy_owner.save!
|
895
|
+
subject << proxy_target << proxy_target_2
|
896
|
+
subject.reset
|
897
|
+
|
898
|
+
not_among_targets.save!
|
899
|
+
end
|
900
|
+
|
901
|
+
it "returns all the targets" do
|
902
|
+
subject.all.should include proxy_target, proxy_target_2
|
903
|
+
subject.all.should_not include proxy_target_3
|
904
|
+
end
|
905
|
+
|
906
|
+
[:limit, :offset, :starts_with].each do |finder_option|
|
907
|
+
it "raises an error when asked to do a #{finder_option}" do
|
908
|
+
expect {
|
909
|
+
subject.all(finder_option => "value")
|
910
|
+
}.to raise_error MassiveRecord::ORM::Relations::Proxy::ReferencesMany::UnsupportedFinderOption
|
911
|
+
end
|
912
|
+
end
|
913
|
+
|
914
|
+
it "does not hit database if targets has been loaded" do
|
915
|
+
subject.load_proxy_target
|
916
|
+
subject.proxy_target_class.should_not_receive :find
|
917
|
+
subject.all
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
describe "with records starts from (proc)" do
|
922
|
+
let(:proxy_target) { Person.new proxy_owner.id+"-friend-1", :name => "T", :age => 2 }
|
923
|
+
let(:proxy_target_2) { Person.new proxy_owner.id+"-friend-2", :name => "H", :age => 9 }
|
924
|
+
let(:not_among_targets) { Person.new "NOT-friend-1", :name => "H", :age => 9 }
|
925
|
+
let(:metadata) { subject.metadata }
|
926
|
+
|
927
|
+
subject { proxy_owner.send(:relation_proxy, 'friends') }
|
928
|
+
|
929
|
+
before do
|
930
|
+
proxy_owner.save!
|
931
|
+
subject << proxy_target << proxy_target_2
|
932
|
+
subject.reset
|
933
|
+
|
934
|
+
not_among_targets.save!
|
935
|
+
end
|
936
|
+
|
937
|
+
it "returns all the targets" do
|
938
|
+
subject.all.should include proxy_target, proxy_target_2
|
939
|
+
subject.all.should_not include proxy_target_3
|
940
|
+
end
|
941
|
+
|
942
|
+
it "accepts to limit the result" do
|
943
|
+
subject.all(:limit => 1).should include proxy_target
|
944
|
+
subject.all.should_not include proxy_target_3, proxy_target_2
|
945
|
+
end
|
946
|
+
|
947
|
+
it "accepts to offset the result" do
|
948
|
+
subject.all(:offset => proxy_owner.id+"-friend-2").should include proxy_target_2
|
949
|
+
subject.all.should_not include proxy_target_3, proxy_target
|
950
|
+
end
|
951
|
+
|
952
|
+
it "accepts to modify the starts_with" do
|
953
|
+
subject.all(:starts_with => proxy_owner.id+"-friend-1").should include proxy_target
|
954
|
+
subject.all.should_not include proxy_target_3, proxy_target_2
|
955
|
+
end
|
956
|
+
|
957
|
+
it "raises an error on invalid starts_with option" do
|
958
|
+
expect {
|
959
|
+
subject.all(:starts_with => "foobar")
|
960
|
+
}.to raise_error MassiveRecord::ORM::Relations::InvalidStartsWithOption
|
961
|
+
end
|
962
|
+
|
963
|
+
it "accepts option offset" do
|
964
|
+
records = subject.all(:offset => proxy_owner.id+"-friend-2")
|
965
|
+
records.should_not include proxy_target, proxy_target_3
|
966
|
+
records.should include proxy_target_2
|
967
|
+
end
|
968
|
+
|
969
|
+
it "does not hit database if targets has been loaded" do
|
970
|
+
subject.load_proxy_target
|
971
|
+
Person.should_not_receive(:do_find)
|
972
|
+
subject.all
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|
976
|
+
|
539
977
|
|
540
978
|
|
541
979
|
describe "#limit" do
|
@@ -575,6 +1013,13 @@ describe TestReferencesManyProxy do
|
|
575
1013
|
subject.load_proxy_target
|
576
1014
|
subject.limit(1).should == [proxy_target]
|
577
1015
|
end
|
1016
|
+
|
1017
|
+
it "returns first record if in a dirty state" do
|
1018
|
+
subject.delete(proxy_target_2)
|
1019
|
+
subject.reset
|
1020
|
+
subject << proxy_target_2
|
1021
|
+
subject.limit(1).should eq [proxy_target]
|
1022
|
+
end
|
578
1023
|
end
|
579
1024
|
|
580
1025
|
|
@@ -619,6 +1064,25 @@ describe TestReferencesManyProxy do
|
|
619
1064
|
subject.load_proxy_target
|
620
1065
|
subject.limit(1).should == [proxy_target]
|
621
1066
|
end
|
1067
|
+
|
1068
|
+
it "returns first record if in a dirty state" do
|
1069
|
+
proxy_target_2.destroy
|
1070
|
+
new_proxy_target = Person.new proxy_owner.id+"-friend-2", :name => "H", :age => 9
|
1071
|
+
subject.reset
|
1072
|
+
subject << new_proxy_target
|
1073
|
+
subject.limit(1).should eq [proxy_target]
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
it "returns first record if in a dirty state, when no objects are saved" do
|
1077
|
+
subject.destroy_all
|
1078
|
+
subject.reset
|
1079
|
+
proxy_owner.stub(:persisted?).and_return false
|
1080
|
+
proxy_owner.stub(:new_record?).and_return true
|
1081
|
+
|
1082
|
+
new_proxy_target = Person.new proxy_owner.id+"-friend-2", :name => "H", :age => 9
|
1083
|
+
subject << new_proxy_target
|
1084
|
+
subject.limit(1).should eq [new_proxy_target]
|
1085
|
+
end
|
622
1086
|
end
|
623
1087
|
end
|
624
1088
|
|