sequel 2.1.0 → 2.2.0
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 +37 -1
- data/Rakefile +2 -2
- data/doc/advanced_associations.rdoc +624 -0
- data/lib/sequel_model.rb +7 -2
- data/lib/sequel_model/association_reflection.rb +112 -2
- data/lib/sequel_model/associations.rb +171 -222
- data/lib/sequel_model/base.rb +28 -7
- data/lib/sequel_model/eager_loading.rb +12 -71
- data/lib/sequel_model/record.rb +143 -14
- data/lib/sequel_model/validations.rb +108 -17
- data/spec/association_reflection_spec.rb +10 -2
- data/spec/associations_spec.rb +449 -94
- data/spec/caching_spec.rb +72 -11
- data/spec/eager_loading_spec.rb +168 -21
- data/spec/hooks_spec.rb +53 -15
- data/spec/model_spec.rb +12 -11
- data/spec/spec_helper.rb +0 -7
- data/spec/validations_spec.rb +39 -16
- metadata +6 -4
@@ -76,10 +76,18 @@ describe Sequel::Model::Associations::AssociationReflection, "#select" do
|
|
76
76
|
@c.association_reflection(:c).should include(:select)
|
77
77
|
@c.association_reflection(:c).select.should == [:par_parents__id]
|
78
78
|
end
|
79
|
-
it "should
|
79
|
+
it "should be the associated_table.* if :select is not present for a many_to_many associaiton" do
|
80
|
+
@c.many_to_many :cs, :class=>'ParParent'
|
81
|
+
@c.association_reflection(:cs).should_not include(:select)
|
82
|
+
@c.association_reflection(:cs).select.should == :par_parents.*
|
83
|
+
end
|
84
|
+
it "should be if :select is not present for a many_to_one and one_to_many associaiton" do
|
85
|
+
@c.one_to_many :cs, :class=>'ParParent'
|
86
|
+
@c.association_reflection(:cs).should_not include(:select)
|
87
|
+
@c.association_reflection(:cs).select.should == nil
|
80
88
|
@c.many_to_one :c, :class=>'ParParent'
|
81
89
|
@c.association_reflection(:c).should_not include(:select)
|
82
|
-
@c.association_reflection(:c).select.should ==
|
90
|
+
@c.association_reflection(:c).select.should == nil
|
83
91
|
end
|
84
92
|
end
|
85
93
|
|
data/spec/associations_spec.rb
CHANGED
@@ -15,20 +15,40 @@ describe Sequel::Model, "associate" do
|
|
15
15
|
klass.association_reflection(:"par_parent1s").associated_class.should == ParParent
|
16
16
|
klass.association_reflection(:"par_parent2s").associated_class.should == ParParent
|
17
17
|
end
|
18
|
+
it "should allow extending the dataset with :extend option" do
|
19
|
+
MODEL_DB.reset
|
20
|
+
klass = Class.new(Sequel::Model(:nodes)) do
|
21
|
+
columns :id, :a_id
|
22
|
+
end
|
23
|
+
mod = Module.new do
|
24
|
+
def blah
|
25
|
+
1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
mod2 = Module.new do
|
29
|
+
def blar
|
30
|
+
2
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
klass.associate :many_to_one, :a, :class=>klass, :extend=>mod
|
35
|
+
klass.associate :one_to_many, :bs, :class=>klass, :extend=>[mod]
|
36
|
+
klass.associate :many_to_many, :cs, :class=>klass, :extend=>[mod, mod2]
|
37
|
+
|
38
|
+
node = klass.load(:id=>1)
|
39
|
+
node.a_dataset.blah.should == 1
|
40
|
+
node.bs_dataset.blah.should == 1
|
41
|
+
node.cs_dataset.blah.should == 1
|
42
|
+
node.cs_dataset.blar.should == 2
|
43
|
+
end
|
18
44
|
end
|
19
45
|
|
20
46
|
describe Sequel::Model, "many_to_one" do
|
21
|
-
|
22
|
-
before(:each) do
|
47
|
+
before do
|
23
48
|
MODEL_DB.reset
|
24
49
|
|
25
50
|
@c2 = Class.new(Sequel::Model(:nodes)) do
|
26
51
|
columns :id, :parent_id, :par_parent_id, :blah
|
27
|
-
def self.create_new(values)
|
28
|
-
obj = self.new(values)
|
29
|
-
obj.instance_variable_set(:@new, false)
|
30
|
-
obj
|
31
|
-
end
|
32
52
|
end
|
33
53
|
|
34
54
|
@dataset = @c2.dataset
|
@@ -42,7 +62,7 @@ describe Sequel::Model, "many_to_one" do
|
|
42
62
|
p.class.should == @c2
|
43
63
|
p.values.should == {:x => 1, :id => 1}
|
44
64
|
|
45
|
-
MODEL_DB.sqls.should == ["SELECT
|
65
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
46
66
|
end
|
47
67
|
|
48
68
|
it "should use implicit class if omitted" do
|
@@ -55,7 +75,7 @@ describe Sequel::Model, "many_to_one" do
|
|
55
75
|
p = d.par_parent
|
56
76
|
p.class.should == ParParent
|
57
77
|
|
58
|
-
MODEL_DB.sqls.should == ["SELECT
|
78
|
+
MODEL_DB.sqls.should == ["SELECT * FROM par_parents WHERE (par_parents.id = 234) LIMIT 1"]
|
59
79
|
end
|
60
80
|
|
61
81
|
it "should use class inside module if given as a string" do
|
@@ -70,7 +90,7 @@ describe Sequel::Model, "many_to_one" do
|
|
70
90
|
p = d.par_parent
|
71
91
|
p.class.should == Par::Parent
|
72
92
|
|
73
|
-
MODEL_DB.sqls.should == ["SELECT
|
93
|
+
MODEL_DB.sqls.should == ["SELECT * FROM parents WHERE (parents.id = 234) LIMIT 1"]
|
74
94
|
end
|
75
95
|
|
76
96
|
it "should use explicit key if given" do
|
@@ -81,13 +101,22 @@ describe Sequel::Model, "many_to_one" do
|
|
81
101
|
p.class.should == @c2
|
82
102
|
p.values.should == {:x => 1, :id => 1}
|
83
103
|
|
84
|
-
MODEL_DB.sqls.should == ["SELECT
|
104
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 567) LIMIT 1"]
|
85
105
|
end
|
86
106
|
|
87
107
|
it "should use :select option if given" do
|
88
108
|
@c2.many_to_one :parent, :class => @c2, :key => :blah, :select=>[:id, :name]
|
89
109
|
@c2.new(:id => 1, :blah => 567).parent
|
90
|
-
MODEL_DB.sqls.should == ["SELECT id, name FROM nodes WHERE (id = 567) LIMIT 1"]
|
110
|
+
MODEL_DB.sqls.should == ["SELECT id, name FROM nodes WHERE (nodes.id = 567) LIMIT 1"]
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should support :order, :limit (only for offset), and :dataset options, as well as a block" do
|
114
|
+
c2 = @c2
|
115
|
+
@c2.many_to_one :child_20, :class => @c2, :key=>:id, :dataset=>proc{c2.filter(:parent_id=>pk)}, :limit=>[10,20], :order=>:name do |ds|
|
116
|
+
ds.filter(:x > 1)
|
117
|
+
end
|
118
|
+
@c2.load(:id => 100).child_20
|
119
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE ((parent_id = 100) AND (x > 1)) ORDER BY name LIMIT 1 OFFSET 20"]
|
91
120
|
end
|
92
121
|
|
93
122
|
it "should return nil if key value is nil" do
|
@@ -107,9 +136,9 @@ describe Sequel::Model, "many_to_one" do
|
|
107
136
|
d = @c2.new(:id => 1, :parent_id=>555)
|
108
137
|
MODEL_DB.sqls.should == []
|
109
138
|
d.parent.should == nil
|
110
|
-
MODEL_DB.sqls.should == ['SELECT
|
139
|
+
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.id = 555) LIMIT 1']
|
111
140
|
d.parent.should == nil
|
112
|
-
MODEL_DB.sqls.should == ['SELECT
|
141
|
+
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.id = 555) LIMIT 1']
|
113
142
|
end
|
114
143
|
|
115
144
|
it "should define a setter method" do
|
@@ -130,7 +159,7 @@ describe Sequel::Model, "many_to_one" do
|
|
130
159
|
it "should not persist changes until saved" do
|
131
160
|
@c2.many_to_one :parent, :class => @c2
|
132
161
|
|
133
|
-
d = @c2.
|
162
|
+
d = @c2.load(:id => 1)
|
134
163
|
MODEL_DB.reset
|
135
164
|
d.parent = @c2.new(:id => 345)
|
136
165
|
MODEL_DB.sqls.should == []
|
@@ -141,14 +170,14 @@ describe Sequel::Model, "many_to_one" do
|
|
141
170
|
it "should set cached instance variable when accessed" do
|
142
171
|
@c2.many_to_one :parent, :class => @c2
|
143
172
|
|
144
|
-
d = @c2.
|
173
|
+
d = @c2.load(:id => 1)
|
145
174
|
MODEL_DB.reset
|
146
175
|
d.parent_id = 234
|
147
176
|
d.associations[:parent].should == nil
|
148
177
|
ds = @c2.dataset
|
149
178
|
def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
|
150
179
|
e = d.parent
|
151
|
-
MODEL_DB.sqls.should == ["SELECT
|
180
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
152
181
|
d.associations[:parent].should == e
|
153
182
|
end
|
154
183
|
|
@@ -182,7 +211,7 @@ describe Sequel::Model, "many_to_one" do
|
|
182
211
|
d.parent_id = 234
|
183
212
|
d.associations[:parent] = 42
|
184
213
|
d.parent(true).should_not == 42
|
185
|
-
MODEL_DB.sqls.should == ["SELECT
|
214
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
186
215
|
end
|
187
216
|
|
188
217
|
it "should have the setter add to the reciprocal one_to_many cached association list if it exists" do
|
@@ -198,16 +227,16 @@ describe Sequel::Model, "many_to_one" do
|
|
198
227
|
MODEL_DB.sqls.should == []
|
199
228
|
d.parent = e
|
200
229
|
e.children.should_not(include(d))
|
201
|
-
MODEL_DB.sqls.should == ['SELECT
|
230
|
+
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
202
231
|
|
203
232
|
MODEL_DB.reset
|
204
233
|
d = @c2.new(:id => 1)
|
205
234
|
e = @c2.new(:id => 2)
|
206
235
|
e.children.should_not(include(d))
|
207
|
-
MODEL_DB.sqls.should == ['SELECT
|
236
|
+
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
208
237
|
d.parent = e
|
209
238
|
e.children.should(include(d))
|
210
|
-
MODEL_DB.sqls.should == ['SELECT
|
239
|
+
MODEL_DB.sqls.should == ['SELECT * FROM nodes WHERE (nodes.parent_id = 2)']
|
211
240
|
end
|
212
241
|
|
213
242
|
it "should have the setter remove the object from the previous associated object's reciprocal one_to_many cached association list if it exists" do
|
@@ -250,16 +279,117 @@ describe Sequel::Model, "many_to_one" do
|
|
250
279
|
it "should have belongs_to alias" do
|
251
280
|
@c2.belongs_to :parent, :class => @c2
|
252
281
|
|
253
|
-
d = @c2.
|
282
|
+
d = @c2.load(:id => 1)
|
254
283
|
MODEL_DB.reset
|
255
284
|
d.parent_id = 234
|
256
285
|
d.associations[:parent].should == nil
|
257
286
|
ds = @c2.dataset
|
258
287
|
def ds.fetch_rows(sql, &block); MODEL_DB.sqls << sql; yield({:id=>234}) end
|
259
288
|
e = d.parent
|
260
|
-
MODEL_DB.sqls.should == ["SELECT
|
289
|
+
MODEL_DB.sqls.should == ["SELECT * FROM nodes WHERE (nodes.id = 234) LIMIT 1"]
|
261
290
|
d.associations[:parent].should == e
|
262
291
|
end
|
292
|
+
|
293
|
+
it "should make the change to the foreign_key value inside a _association= method" do
|
294
|
+
@c2.many_to_one :parent, :class => @c2
|
295
|
+
@c2.private_instance_methods.sort.should(include("_parent="))
|
296
|
+
p = @c2.new
|
297
|
+
c = @c2.load(:id=>123)
|
298
|
+
def p._parent=(x)
|
299
|
+
@x = x
|
300
|
+
end
|
301
|
+
p.should_not_receive(:parent_id=)
|
302
|
+
p.parent = c
|
303
|
+
p.instance_variable_get(:@x).should == c
|
304
|
+
end
|
305
|
+
|
306
|
+
it "should support (before|after)_(add|remove) callbacks" do
|
307
|
+
h = []
|
308
|
+
@c2.many_to_one :parent, :class => @c2, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
|
309
|
+
@c2.class_eval do
|
310
|
+
@@blah = h
|
311
|
+
def []=(a, v)
|
312
|
+
a == :parent_id ? (@@blah << (v ? 4 : 5)) : super
|
313
|
+
end
|
314
|
+
def blah(x)
|
315
|
+
@@blah << x.pk
|
316
|
+
end
|
317
|
+
def blahr(x)
|
318
|
+
@@blah << 6
|
319
|
+
end
|
320
|
+
end
|
321
|
+
p = @c2.load(:id=>10)
|
322
|
+
c = @c2.load(:id=>123)
|
323
|
+
h.should == []
|
324
|
+
p.parent = c
|
325
|
+
h.should == [10, -123, 123, 4, 3]
|
326
|
+
p.parent = nil
|
327
|
+
h.should == [10, -123, 123, 4, 3, 123, 5, 6]
|
328
|
+
end
|
329
|
+
|
330
|
+
it "should support after_load association callback" do
|
331
|
+
h = []
|
332
|
+
@c2.many_to_one :parent, :class => @c2, :after_load=>[proc{|x,y| h << [x.pk, y.pk]}, :al]
|
333
|
+
@c2.class_eval do
|
334
|
+
@@blah = h
|
335
|
+
def al(v)
|
336
|
+
@@blah << v.pk
|
337
|
+
end
|
338
|
+
def @dataset.fetch_rows(sql)
|
339
|
+
yield({:id=>20})
|
340
|
+
end
|
341
|
+
end
|
342
|
+
p = @c2.load(:id=>10, :parent_id=>20)
|
343
|
+
parent = p.parent
|
344
|
+
h.should == [[10, 20], 20]
|
345
|
+
parent.pk.should == 20
|
346
|
+
end
|
347
|
+
|
348
|
+
it "should raise error and not call internal add or remove method if before callback returns false, even if raise_on_save_failure is false" do
|
349
|
+
# The reason for this is that assignment in ruby always returns the argument instead of the result
|
350
|
+
# of the method, so we can't return nil to signal that the association callback prevented the modification
|
351
|
+
p = @c2.new
|
352
|
+
c = @c2.load(:id=>123)
|
353
|
+
p.raise_on_save_failure = false
|
354
|
+
@c2.many_to_one :parent, :class => @c2, :before_add=>:ba, :before_remove=>:br
|
355
|
+
p.should_receive(:ba).once.with(c).and_return(false)
|
356
|
+
p.should_not_receive(:_parent=)
|
357
|
+
proc{p.parent = c}.should raise_error(Sequel::Error)
|
358
|
+
p.parent.should == nil
|
359
|
+
p.associations[:parent] = c
|
360
|
+
p.parent.should == c
|
361
|
+
p.should_receive(:br).once.with(c).and_return(false)
|
362
|
+
proc{p.parent = nil}.should raise_error(Sequel::Error)
|
363
|
+
end
|
364
|
+
|
365
|
+
it "should call the remove callbacks for the previous object and the add callbacks for the new object" do
|
366
|
+
c = @c2.load(:id=>123)
|
367
|
+
d = @c2.load(:id=>321)
|
368
|
+
p = @c2.new
|
369
|
+
p.associations[:parent] = d
|
370
|
+
h = []
|
371
|
+
@c2.many_to_one :parent, :class => @c2, :before_add=>:ba, :before_remove=>:br, :after_add=>:aa, :after_remove=>:ar
|
372
|
+
@c2.class_eval do
|
373
|
+
@@blah = h
|
374
|
+
def []=(a, v)
|
375
|
+
a == :parent_id ? (@@blah << 5) : super
|
376
|
+
end
|
377
|
+
def ba(x)
|
378
|
+
@@blah << x.pk
|
379
|
+
end
|
380
|
+
def br(x)
|
381
|
+
@@blah << x.pk * -1
|
382
|
+
end
|
383
|
+
def aa(x)
|
384
|
+
@@blah << x.pk * 2
|
385
|
+
end
|
386
|
+
def ar(x)
|
387
|
+
@@blah << x.pk * -2
|
388
|
+
end
|
389
|
+
end
|
390
|
+
p.parent = c
|
391
|
+
h.should == [-321, 123, 5, 246, -642]
|
392
|
+
end
|
263
393
|
end
|
264
394
|
|
265
395
|
describe Sequel::Model, "one_to_many" do
|
@@ -301,7 +431,7 @@ describe Sequel::Model, "one_to_many" do
|
|
301
431
|
n = @c2.new(:id => 1234)
|
302
432
|
a = n.attributes_dataset
|
303
433
|
a.should be_a_kind_of(Sequel::Dataset)
|
304
|
-
a.sql.should == 'SELECT
|
434
|
+
a.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234)'
|
305
435
|
end
|
306
436
|
|
307
437
|
it "should use implicit class if omitted" do
|
@@ -313,7 +443,7 @@ describe Sequel::Model, "one_to_many" do
|
|
313
443
|
n = @c2.new(:id => 1234)
|
314
444
|
v = n.historical_values_dataset
|
315
445
|
v.should be_a_kind_of(Sequel::Dataset)
|
316
|
-
v.sql.should == 'SELECT
|
446
|
+
v.sql.should == 'SELECT * FROM historical_values WHERE (historical_values.node_id = 1234)'
|
317
447
|
v.model_classes.should == {nil => HistoricalValue}
|
318
448
|
end
|
319
449
|
|
@@ -328,7 +458,7 @@ describe Sequel::Model, "one_to_many" do
|
|
328
458
|
n = @c2.new(:id => 1234)
|
329
459
|
v = n.historical_values_dataset
|
330
460
|
v.should be_a_kind_of(Sequel::Dataset)
|
331
|
-
v.sql.should == 'SELECT
|
461
|
+
v.sql.should == 'SELECT * FROM values WHERE (values.node_id = 1234)'
|
332
462
|
v.model_classes.should == {nil => Historical::Value}
|
333
463
|
end
|
334
464
|
|
@@ -338,7 +468,7 @@ describe Sequel::Model, "one_to_many" do
|
|
338
468
|
n = @c2.new(:id => 1234)
|
339
469
|
a = n.attributes_dataset
|
340
470
|
a.should be_a_kind_of(Sequel::Dataset)
|
341
|
-
a.sql.should == 'SELECT
|
471
|
+
a.sql.should == 'SELECT * FROM attributes WHERE (attributes.nodeid = 1234)'
|
342
472
|
end
|
343
473
|
|
344
474
|
it "should define an add_ method" do
|
@@ -387,21 +517,21 @@ describe Sequel::Model, "one_to_many" do
|
|
387
517
|
@c2.one_to_many :attributes, :class => @c1, :select => [:id, :name]
|
388
518
|
|
389
519
|
n = @c2.new(:id => 1234)
|
390
|
-
n.attributes_dataset.sql.should == "SELECT id, name FROM attributes WHERE (node_id = 1234)"
|
520
|
+
n.attributes_dataset.sql.should == "SELECT id, name FROM attributes WHERE (attributes.node_id = 1234)"
|
391
521
|
end
|
392
522
|
|
393
523
|
it "should support an order option" do
|
394
524
|
@c2.one_to_many :attributes, :class => @c1, :order => :kind
|
395
525
|
|
396
526
|
n = @c2.new(:id => 1234)
|
397
|
-
n.attributes_dataset.sql.should == "SELECT
|
527
|
+
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind"
|
398
528
|
end
|
399
529
|
|
400
530
|
it "should support an array for the order option" do
|
401
531
|
@c2.one_to_many :attributes, :class => @c1, :order => [:kind1, :kind2]
|
402
532
|
|
403
533
|
n = @c2.new(:id => 1234)
|
404
|
-
n.attributes_dataset.sql.should == "SELECT
|
534
|
+
n.attributes_dataset.sql.should == "SELECT * FROM attributes WHERE (attributes.node_id = 1234) ORDER BY kind1, kind2"
|
405
535
|
end
|
406
536
|
|
407
537
|
it "should return array with all members of the association" do
|
@@ -414,7 +544,7 @@ describe Sequel::Model, "one_to_many" do
|
|
414
544
|
atts.first.should be_a_kind_of(@c1)
|
415
545
|
atts.first.values.should == {}
|
416
546
|
|
417
|
-
MODEL_DB.sqls.should == ['SELECT
|
547
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
418
548
|
end
|
419
549
|
|
420
550
|
it "should accept a block" do
|
@@ -429,10 +559,10 @@ describe Sequel::Model, "one_to_many" do
|
|
429
559
|
atts.first.should be_a_kind_of(@c1)
|
430
560
|
atts.first.values.should == {}
|
431
561
|
|
432
|
-
MODEL_DB.sqls.should == ['SELECT
|
562
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL))']
|
433
563
|
end
|
434
564
|
|
435
|
-
it "should support order option with block" do
|
565
|
+
it "should support :order option with block" do
|
436
566
|
@c2.one_to_many :attributes, :class => @c1, :order => :kind do |ds|
|
437
567
|
ds.filter(:xxx => @xxx)
|
438
568
|
end
|
@@ -444,21 +574,38 @@ describe Sequel::Model, "one_to_many" do
|
|
444
574
|
atts.first.should be_a_kind_of(@c1)
|
445
575
|
atts.first.values.should == {}
|
446
576
|
|
447
|
-
MODEL_DB.sqls.should == ['SELECT
|
577
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx IS NULL)) ORDER BY kind']
|
448
578
|
end
|
449
579
|
|
450
580
|
it "should have the block argument affect the _dataset method" do
|
451
581
|
@c2.one_to_many :attributes, :class => @c1 do |ds|
|
452
582
|
ds.filter(:xxx => 456)
|
453
583
|
end
|
454
|
-
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT
|
584
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((attributes.node_id = 1234) AND (xxx = 456))'
|
585
|
+
end
|
586
|
+
|
587
|
+
it "should support a :dataset option that is used instead of the default" do
|
588
|
+
c1 = @c1
|
589
|
+
@c2.one_to_many :all_other_attributes, :class => @c1, :dataset=>proc{c1.filter(:nodeid=>pk).invert}, :order=>:a, :limit=>10 do |ds|
|
590
|
+
ds.filter(:xxx => 5)
|
591
|
+
end
|
592
|
+
|
593
|
+
@c2.new(:id => 1234).all_other_attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE ((nodeid != 1234) AND (xxx = 5)) ORDER BY a LIMIT 10'
|
594
|
+
n = @c2.new(:id => 1234)
|
595
|
+
atts = n.all_other_attributes
|
596
|
+
atts.should be_a_kind_of(Array)
|
597
|
+
atts.size.should == 1
|
598
|
+
atts.first.should be_a_kind_of(@c1)
|
599
|
+
atts.first.values.should == {}
|
600
|
+
|
601
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE ((nodeid != 1234) AND (xxx = 5)) ORDER BY a LIMIT 10']
|
455
602
|
end
|
456
603
|
|
457
604
|
it "should support a :limit option" do
|
458
605
|
@c2.one_to_many :attributes, :class => @c1 , :limit=>10
|
459
|
-
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT
|
606
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234) LIMIT 10'
|
460
607
|
@c2.one_to_many :attributes, :class => @c1 , :limit=>[10,10]
|
461
|
-
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT
|
608
|
+
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT * FROM attributes WHERE (attributes.node_id = 1234) LIMIT 10 OFFSET 10'
|
462
609
|
end
|
463
610
|
|
464
611
|
it "should have the :eager option affect the _dataset method" do
|
@@ -474,7 +621,7 @@ describe Sequel::Model, "one_to_many" do
|
|
474
621
|
n.associations.include?(:attributes).should == false
|
475
622
|
atts = n.attributes
|
476
623
|
atts.should == n.associations[:attributes]
|
477
|
-
MODEL_DB.sqls.should == ['SELECT
|
624
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
478
625
|
end
|
479
626
|
|
480
627
|
it "should use cached instance variable if available" do
|
@@ -494,7 +641,7 @@ describe Sequel::Model, "one_to_many" do
|
|
494
641
|
MODEL_DB.reset
|
495
642
|
n.associations[:attributes] = 42
|
496
643
|
n.attributes(true).should_not == 42
|
497
|
-
MODEL_DB.sqls.should == ['SELECT
|
644
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
498
645
|
end
|
499
646
|
|
500
647
|
it "should add item to cached instance variable if it exists when calling add_" do
|
@@ -563,7 +710,7 @@ describe Sequel::Model, "one_to_many" do
|
|
563
710
|
atts.first.should be_a_kind_of(@c1)
|
564
711
|
atts.first.values.should == {}
|
565
712
|
|
566
|
-
MODEL_DB.sqls.should == ['SELECT
|
713
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
567
714
|
end
|
568
715
|
|
569
716
|
it "should populate the reciprocal many_to_one instance variable when loading the one_to_many association" do
|
@@ -572,7 +719,7 @@ describe Sequel::Model, "one_to_many" do
|
|
572
719
|
|
573
720
|
n = @c2.new(:id => 1234)
|
574
721
|
atts = n.attributes
|
575
|
-
MODEL_DB.sqls.should == ['SELECT
|
722
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
576
723
|
atts.should be_a_kind_of(Array)
|
577
724
|
atts.size.should == 1
|
578
725
|
atts.first.should be_a_kind_of(@c1)
|
@@ -587,7 +734,7 @@ describe Sequel::Model, "one_to_many" do
|
|
587
734
|
|
588
735
|
n = @c2.new(:id => 1234)
|
589
736
|
atts = n.attributes
|
590
|
-
MODEL_DB.sqls.should == ['SELECT
|
737
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
591
738
|
atts.should be_a_kind_of(Array)
|
592
739
|
atts.size.should == 1
|
593
740
|
atts.first.should be_a_kind_of(@c1)
|
@@ -649,7 +796,7 @@ describe Sequel::Model, "one_to_many" do
|
|
649
796
|
it "should add a getter method if the :one_to_one option is true" do
|
650
797
|
@c2.one_to_many :attributes, :class => @c1, :one_to_one=>true
|
651
798
|
att = @c2.new(:id => 1234).attribute
|
652
|
-
MODEL_DB.sqls.should == ['SELECT
|
799
|
+
MODEL_DB.sqls.should == ['SELECT * FROM attributes WHERE (attributes.node_id = 1234)']
|
653
800
|
att.should be_a_kind_of(@c1)
|
654
801
|
att.values.should == {}
|
655
802
|
end
|
@@ -682,8 +829,9 @@ describe Sequel::Model, "one_to_many" do
|
|
682
829
|
MODEL_DB.sqls.clear
|
683
830
|
attrib = @c1.load(:id=>3)
|
684
831
|
@c2.new(:id => 1234).attribute = attrib
|
685
|
-
MODEL_DB.sqls.should ==
|
686
|
-
|
832
|
+
MODEL_DB.sqls.length.should == 2
|
833
|
+
MODEL_DB.sqls.first.should =~ /UPDATE attributes SET (node_id = 1234, id = 3|id = 3, node_id = 1234) WHERE \(id = 3\)/
|
834
|
+
MODEL_DB.sqls.last.should == 'UPDATE attributes SET node_id = NULL WHERE ((node_id = 1234) AND (id != 3))'
|
687
835
|
end
|
688
836
|
|
689
837
|
it "should raise an error if the one_to_one getter would be the same as the association name" do
|
@@ -703,6 +851,113 @@ describe Sequel::Model, "one_to_many" do
|
|
703
851
|
meths.should(include("add_attribute"))
|
704
852
|
meths.should(include("attributes_dataset"))
|
705
853
|
end
|
854
|
+
|
855
|
+
it "should call an _add_ method internally to add attributes" do
|
856
|
+
@c2.one_to_many :attributes, :class => @c1
|
857
|
+
@c2.private_instance_methods.sort.should(include("_add_attribute"))
|
858
|
+
p = @c2.load(:id=>10)
|
859
|
+
c = @c1.load(:id=>123)
|
860
|
+
def p._add_attribute(x)
|
861
|
+
@x = x
|
862
|
+
end
|
863
|
+
c.should_not_receive(:node_id=)
|
864
|
+
p.add_attribute(c)
|
865
|
+
p.instance_variable_get(:@x).should == c
|
866
|
+
end
|
867
|
+
|
868
|
+
it "should call a _remove_ method internally to remove attributes" do
|
869
|
+
@c2.one_to_many :attributes, :class => @c1
|
870
|
+
@c2.private_instance_methods.sort.should(include("_remove_attribute"))
|
871
|
+
p = @c2.load(:id=>10)
|
872
|
+
c = @c1.load(:id=>123)
|
873
|
+
def p._remove_attribute(x)
|
874
|
+
@x = x
|
875
|
+
end
|
876
|
+
c.should_not_receive(:node_id=)
|
877
|
+
p.remove_attribute(c)
|
878
|
+
p.instance_variable_get(:@x).should == c
|
879
|
+
end
|
880
|
+
|
881
|
+
it "should support (before|after)_(add|remove) callbacks" do
|
882
|
+
h = []
|
883
|
+
@c2.one_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
|
884
|
+
@c2.class_eval do
|
885
|
+
@@blah = h
|
886
|
+
def _add_attribute(v)
|
887
|
+
@@blah << 4
|
888
|
+
end
|
889
|
+
def _remove_attribute(v)
|
890
|
+
@@blah << 5
|
891
|
+
end
|
892
|
+
def blah(x)
|
893
|
+
@@blah << x.pk
|
894
|
+
end
|
895
|
+
def blahr(x)
|
896
|
+
@@blah << 6
|
897
|
+
end
|
898
|
+
end
|
899
|
+
p = @c2.load(:id=>10)
|
900
|
+
c = @c1.load(:id=>123)
|
901
|
+
h.should == []
|
902
|
+
p.add_attribute(c)
|
903
|
+
h.should == [10, -123, 123, 4, 3]
|
904
|
+
p.remove_attribute(c)
|
905
|
+
h.should == [10, -123, 123, 4, 3, 123, 5, 6]
|
906
|
+
end
|
907
|
+
|
908
|
+
it "should support after_load association callback" do
|
909
|
+
h = []
|
910
|
+
@c2.one_to_many :attributes, :class => @c1, :after_load=>[proc{|x,y| h << [x.pk, y.collect{|z|z.pk}]}, :al]
|
911
|
+
@c2.class_eval do
|
912
|
+
@@blah = h
|
913
|
+
def al(v)
|
914
|
+
v.each{|x| @@blah << x.pk}
|
915
|
+
end
|
916
|
+
end
|
917
|
+
@c1.class_eval do
|
918
|
+
def @dataset.fetch_rows(sql)
|
919
|
+
yield({:id=>20})
|
920
|
+
yield({:id=>30})
|
921
|
+
end
|
922
|
+
end
|
923
|
+
p = @c2.load(:id=>10, :parent_id=>20)
|
924
|
+
attributes = p.attributes
|
925
|
+
h.should == [[10, [20, 30]], 20, 30]
|
926
|
+
attributes.collect{|a| a.pk}.should == [20, 30]
|
927
|
+
end
|
928
|
+
|
929
|
+
it "should raise error and not call internal add or remove method if before callback returns false if raise_on_save_failure is true" do
|
930
|
+
p = @c2.load(:id=>10)
|
931
|
+
c = @c1.load(:id=>123)
|
932
|
+
@c2.one_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
|
933
|
+
p.should_receive(:ba).once.with(c).and_return(false)
|
934
|
+
p.should_not_receive(:_add_attribute)
|
935
|
+
p.should_not_receive(:_remove_attribute)
|
936
|
+
p.associations[:attributes] = []
|
937
|
+
proc{p.add_attribute(c)}.should raise_error(Sequel::Error)
|
938
|
+
p.attributes.should == []
|
939
|
+
p.associations[:attributes] = [c]
|
940
|
+
p.should_receive(:br).once.with(c).and_return(false)
|
941
|
+
proc{p.remove_attribute(c)}.should raise_error(Sequel::Error)
|
942
|
+
p.attributes.should == [c]
|
943
|
+
end
|
944
|
+
|
945
|
+
it "should return nil and not call internal add or remove method if before callback returns false if raise_on_save_failure is false" do
|
946
|
+
p = @c2.load(:id=>10)
|
947
|
+
c = @c1.load(:id=>123)
|
948
|
+
p.raise_on_save_failure = false
|
949
|
+
@c2.one_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
|
950
|
+
p.should_receive(:ba).once.with(c).and_return(false)
|
951
|
+
p.should_not_receive(:_add_attribute)
|
952
|
+
p.should_not_receive(:_remove_attribute)
|
953
|
+
p.associations[:attributes] = []
|
954
|
+
p.add_attribute(c).should == nil
|
955
|
+
p.attributes.should == []
|
956
|
+
p.associations[:attributes] = [c]
|
957
|
+
p.should_receive(:br).once.with(c).and_return(false)
|
958
|
+
p.remove_attribute(c).should == nil
|
959
|
+
p.attributes.should == [c]
|
960
|
+
end
|
706
961
|
end
|
707
962
|
|
708
963
|
describe Sequel::Model, "many_to_many" do
|
@@ -829,7 +1084,7 @@ describe Sequel::Model, "many_to_many" do
|
|
829
1084
|
MODEL_DB.sqls.first.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 555)'
|
830
1085
|
end
|
831
1086
|
|
832
|
-
it "should allow the order option while accepting a block" do
|
1087
|
+
it "should allow the :order option while accepting a block" do
|
833
1088
|
@c2.many_to_many :attributes, :class => @c1, :order=>[:blah1, :blah2] do |ds|
|
834
1089
|
ds.filter(:xxx => @xxx)
|
835
1090
|
end
|
@@ -850,6 +1105,22 @@ describe Sequel::Model, "many_to_many" do
|
|
850
1105
|
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) WHERE (xxx = 456)'
|
851
1106
|
end
|
852
1107
|
|
1108
|
+
it "should support a :dataset option that is used instead of the default" do
|
1109
|
+
c1 = @c1
|
1110
|
+
@c2.many_to_many :attributes, :class => @c1, :dataset=>proc{c1.join_table(:natural, :an).filter(:an__nodeid=>pk)}, :order=> :a, :limit=>10, :select=>nil do |ds|
|
1111
|
+
ds.filter(:xxx => @xxx)
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
n = @c2.new(:id => 1234)
|
1115
|
+
n.xxx = 555
|
1116
|
+
n.attributes_dataset.sql.should == 'SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10'
|
1117
|
+
a = n.attributes
|
1118
|
+
a.should be_a_kind_of(Array)
|
1119
|
+
a.size.should == 1
|
1120
|
+
a.first.should be_a_kind_of(@c1)
|
1121
|
+
MODEL_DB.sqls.first.should == 'SELECT * FROM attributes NATURAL JOIN an WHERE ((an.nodeid = 1234) AND (xxx = 555)) ORDER BY a LIMIT 10'
|
1122
|
+
end
|
1123
|
+
|
853
1124
|
it "should support a :limit option" do
|
854
1125
|
@c2.many_to_many :attributes, :class => @c1 , :limit=>10
|
855
1126
|
@c2.new(:id => 1234).attributes_dataset.sql.should == 'SELECT attributes.* FROM attributes INNER JOIN attributes_nodes ON ((attributes_nodes.attribute_id = attributes.id) AND (attributes_nodes.node_id = 1234)) LIMIT 10'
|
@@ -1055,10 +1326,118 @@ describe Sequel::Model, "many_to_many" do
|
|
1055
1326
|
node.remove_all_attributes
|
1056
1327
|
attrib.associations[:nodes].should == []
|
1057
1328
|
end
|
1329
|
+
|
1330
|
+
it "should call an _add_ method internally to add attributes" do
|
1331
|
+
@c2.many_to_many :attributes, :class => @c1
|
1332
|
+
@c2.private_instance_methods.sort.should(include("_add_attribute"))
|
1333
|
+
p = @c2.load(:id=>10)
|
1334
|
+
c = @c1.load(:id=>123)
|
1335
|
+
def p._add_attribute(x)
|
1336
|
+
@x = x
|
1337
|
+
end
|
1338
|
+
p.add_attribute(c)
|
1339
|
+
p.instance_variable_get(:@x).should == c
|
1340
|
+
MODEL_DB.sqls.should == []
|
1341
|
+
end
|
1342
|
+
|
1343
|
+
it "should call a _remove_ method internally to remove attributes" do
|
1344
|
+
@c2.many_to_many :attributes, :class => @c1
|
1345
|
+
@c2.private_instance_methods.sort.should(include("_remove_attribute"))
|
1346
|
+
p = @c2.load(:id=>10)
|
1347
|
+
c = @c1.load(:id=>123)
|
1348
|
+
def p._remove_attribute(x)
|
1349
|
+
@x = x
|
1350
|
+
end
|
1351
|
+
p.remove_attribute(c)
|
1352
|
+
p.instance_variable_get(:@x).should == c
|
1353
|
+
MODEL_DB.sqls.should == []
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
it "should support (before|after)_(add|remove) callbacks" do
|
1357
|
+
h = []
|
1358
|
+
@c2.many_to_many :attributes, :class => @c1, :before_add=>[proc{|x,y| h << x.pk; h << -y.pk}, :blah], :after_add=>proc{h << 3}, :before_remove=>:blah, :after_remove=>[:blahr]
|
1359
|
+
@c2.class_eval do
|
1360
|
+
@@blah = h
|
1361
|
+
def _add_attribute(v)
|
1362
|
+
@@blah << 4
|
1363
|
+
end
|
1364
|
+
def _remove_attribute(v)
|
1365
|
+
@@blah << 5
|
1366
|
+
end
|
1367
|
+
def blah(x)
|
1368
|
+
@@blah << x.pk
|
1369
|
+
end
|
1370
|
+
def blahr(x)
|
1371
|
+
@@blah << 6
|
1372
|
+
end
|
1373
|
+
end
|
1374
|
+
p = @c2.load(:id=>10)
|
1375
|
+
c = @c1.load(:id=>123)
|
1376
|
+
h.should == []
|
1377
|
+
p.add_attribute(c)
|
1378
|
+
h.should == [10, -123, 123, 4, 3]
|
1379
|
+
p.remove_attribute(c)
|
1380
|
+
h.should == [10, -123, 123, 4, 3, 123, 5, 6]
|
1381
|
+
end
|
1382
|
+
|
1383
|
+
it "should support after_load association callback" do
|
1384
|
+
h = []
|
1385
|
+
@c2.many_to_many :attributes, :class => @c1, :after_load=>[proc{|x,y| h << [x.pk, y.collect{|z|z.pk}]}, :al]
|
1386
|
+
@c2.class_eval do
|
1387
|
+
@@blah = h
|
1388
|
+
def al(v)
|
1389
|
+
v.each{|x| @@blah << x.pk}
|
1390
|
+
end
|
1391
|
+
end
|
1392
|
+
@c1.class_eval do
|
1393
|
+
def @dataset.fetch_rows(sql)
|
1394
|
+
yield({:id=>20})
|
1395
|
+
yield({:id=>30})
|
1396
|
+
end
|
1397
|
+
end
|
1398
|
+
p = @c2.load(:id=>10, :parent_id=>20)
|
1399
|
+
attributes = p.attributes
|
1400
|
+
h.should == [[10, [20, 30]], 20, 30]
|
1401
|
+
attributes.collect{|a| a.pk}.should == [20, 30]
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
it "should raise error and not call internal add or remove method if before callback returns false if raise_on_save_failure is true" do
|
1405
|
+
p = @c2.load(:id=>10)
|
1406
|
+
c = @c1.load(:id=>123)
|
1407
|
+
@c2.many_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
|
1408
|
+
p.should_receive(:ba).once.with(c).and_return(false)
|
1409
|
+
p.should_not_receive(:_add_attribute)
|
1410
|
+
p.should_not_receive(:_remove_attribute)
|
1411
|
+
p.associations[:attributes] = []
|
1412
|
+
p.raise_on_save_failure = true
|
1413
|
+
proc{p.add_attribute(c)}.should raise_error(Sequel::Error)
|
1414
|
+
p.attributes.should == []
|
1415
|
+
p.associations[:attributes] = [c]
|
1416
|
+
p.should_receive(:br).once.with(c).and_return(false)
|
1417
|
+
proc{p.remove_attribute(c)}.should raise_error(Sequel::Error)
|
1418
|
+
p.attributes.should == [c]
|
1419
|
+
end
|
1420
|
+
|
1421
|
+
it "should return nil and not call internal add or remove method if before callback returns false if raise_on_save_failure is false" do
|
1422
|
+
p = @c2.load(:id=>10)
|
1423
|
+
c = @c1.load(:id=>123)
|
1424
|
+
p.raise_on_save_failure = false
|
1425
|
+
@c2.many_to_many :attributes, :class => @c1, :before_add=>:ba, :before_remove=>:br
|
1426
|
+
p.should_receive(:ba).once.with(c).and_return(false)
|
1427
|
+
p.should_not_receive(:_add_attribute)
|
1428
|
+
p.should_not_receive(:_remove_attribute)
|
1429
|
+
p.associations[:attributes] = []
|
1430
|
+
p.add_attribute(c).should == nil
|
1431
|
+
p.attributes.should == []
|
1432
|
+
p.associations[:attributes] = [c]
|
1433
|
+
p.should_receive(:br).once.with(c).and_return(false)
|
1434
|
+
p.remove_attribute(c).should == nil
|
1435
|
+
p.attributes.should == [c]
|
1436
|
+
end
|
1058
1437
|
end
|
1059
1438
|
|
1060
|
-
describe Sequel::Model, "
|
1061
|
-
before
|
1439
|
+
describe Sequel::Model, " association reflection methods" do
|
1440
|
+
before do
|
1062
1441
|
MODEL_DB.reset
|
1063
1442
|
@c1 = Class.new(Sequel::Model(:nodes)) do
|
1064
1443
|
def self.name; 'Node'; end
|
@@ -1066,64 +1445,40 @@ describe Sequel::Model, "all_association_reflections" do
|
|
1066
1445
|
end
|
1067
1446
|
end
|
1068
1447
|
|
1069
|
-
it "should include all association reflection hashes" do
|
1448
|
+
it "#all_association_reflections should include all association reflection hashes" do
|
1070
1449
|
@c1.all_association_reflections.should == []
|
1450
|
+
|
1071
1451
|
@c1.associate :many_to_one, :parent, :class => @c1
|
1072
|
-
@c1.all_association_reflections.should == [
|
1073
|
-
|
1074
|
-
|
1075
|
-
:graph_join_type=>:left_outer, :graph_conditions=>[], :eager_block => nil, :model => @c1
|
1076
|
-
}]
|
1077
|
-
@c1.associate :one_to_many, :children, :class => @c1
|
1078
|
-
@c1.all_association_reflections.sort_by{|x|x[:name].to_s}.should == [{
|
1079
|
-
:type => :one_to_many, :name => :children, :class_name => 'Node',
|
1080
|
-
:class => @c1, :key => :node_id, :block => nil, :cache => true,
|
1081
|
-
:graph_join_type=>:left_outer, :graph_conditions=>[], :eager_block => nil, :model => @c1}, {
|
1082
|
-
:type => :many_to_one, :name => :parent, :class_name => 'Node',
|
1083
|
-
:class => @c1, :key => :parent_id, :block => nil, :cache => true,
|
1084
|
-
:graph_join_type=>:left_outer, :graph_conditions=>[], :eager_block => nil, :model => @c1}]
|
1085
|
-
end
|
1086
|
-
end
|
1452
|
+
@c1.all_association_reflections.collect{|v| v[:name]}.should == [:parent]
|
1453
|
+
@c1.all_association_reflections.collect{|v| v[:type]}.should == [:many_to_one]
|
1454
|
+
@c1.all_association_reflections.collect{|v| v[:class]}.should == [@c1]
|
1087
1455
|
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
@c1
|
1092
|
-
|
1093
|
-
def self.to_s; 'Node'; end
|
1094
|
-
end
|
1456
|
+
@c1.associate :one_to_many, :children, :class => @c1
|
1457
|
+
@c1.all_association_reflections.sort_by{|x|x[:name].to_s}
|
1458
|
+
@c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:name]}.should == [:children, :parent]
|
1459
|
+
@c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:type]}.should == [:one_to_many, :many_to_one]
|
1460
|
+
@c1.all_association_reflections.sort_by{|x|x[:name].to_s}.collect{|v| v[:class]}.should == [@c1, @c1]
|
1095
1461
|
end
|
1096
1462
|
|
1097
|
-
it "should return nil for nonexistent association" do
|
1463
|
+
it "#association_reflection should return nil for nonexistent association" do
|
1098
1464
|
@c1.association_reflection(:blah).should == nil
|
1099
1465
|
end
|
1100
1466
|
|
1101
|
-
it "should return association reflection hash if association exists" do
|
1467
|
+
it "#association_reflection should return association reflection hash if association exists" do
|
1102
1468
|
@c1.associate :many_to_one, :parent, :class => @c1
|
1103
|
-
@c1.association_reflection(:parent).should
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
}
|
1108
|
-
@c1.associate :one_to_many, :children, :class => @c1
|
1109
|
-
@c1.association_reflection(:children).should == {
|
1110
|
-
:type => :one_to_many, :name => :children, :class_name => 'Node',
|
1111
|
-
:class => @c1, :key => :node_id, :block => nil, :cache => true,
|
1112
|
-
:graph_join_type=>:left_outer, :graph_conditions=>[], :eager_block => nil, :model => @c1
|
1113
|
-
}
|
1114
|
-
end
|
1115
|
-
end
|
1469
|
+
@c1.association_reflection(:parent).should be_a_kind_of(Sequel::Model::Associations::AssociationReflection)
|
1470
|
+
@c1.association_reflection(:parent)[:name].should == :parent
|
1471
|
+
@c1.association_reflection(:parent)[:type].should == :many_to_one
|
1472
|
+
@c1.association_reflection(:parent)[:class].should == @c1
|
1116
1473
|
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
@c1
|
1121
|
-
|
1122
|
-
def self.to_s; 'Node'; end
|
1123
|
-
end
|
1474
|
+
@c1.associate :one_to_many, :children, :class => @c1
|
1475
|
+
@c1.association_reflection(:children).should be_a_kind_of(Sequel::Model::Associations::AssociationReflection)
|
1476
|
+
@c1.association_reflection(:children)[:name].should == :children
|
1477
|
+
@c1.association_reflection(:children)[:type].should == :one_to_many
|
1478
|
+
@c1.association_reflection(:children)[:class].should == @c1
|
1124
1479
|
end
|
1125
1480
|
|
1126
|
-
it "should include all association names" do
|
1481
|
+
it "#associations should include all association names" do
|
1127
1482
|
@c1.associations.should == []
|
1128
1483
|
@c1.associate :many_to_one, :parent, :class => @c1
|
1129
1484
|
@c1.associations.should == [:parent]
|