ranked-model 0.4.0 → 0.4.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +2 -0
- data/.rspec +1 -0
- data/.travis.yml +43 -74
- data/Appraisals +72 -0
- data/Gemfile +7 -23
- data/Readme.mkd +139 -19
- data/gemfiles/rails_4_2.gemfile +23 -0
- data/gemfiles/rails_5_0.gemfile +22 -0
- data/gemfiles/rails_5_1.gemfile +22 -0
- data/gemfiles/rails_5_2.gemfile +22 -0
- data/gemfiles/rails_6_0.gemfile +22 -0
- data/lib/ranked-model.rb +20 -5
- data/lib/ranked-model/ranker.rb +91 -70
- data/lib/ranked-model/version.rb +1 -1
- data/ranked-model.gemspec +9 -8
- data/spec/duck-model/column_default_ducks_spec.rb +29 -0
- data/spec/duck-model/duck_spec.rb +207 -78
- data/spec/duck-model/lots_of_ducks_spec.rb +50 -38
- data/spec/duck-model/wrong_ducks_spec.rb +11 -0
- data/spec/ego-model/ego_spec.rb +3 -3
- data/spec/number-model/number_spec.rb +39 -0
- data/spec/player-model/records_already_exist_spec.rb +1 -1
- data/spec/ranked-model/ranker_spec.rb +18 -0
- data/spec/ranked-model/version_spec.rb +1 -1
- data/spec/spec_helper.rb +7 -0
- data/spec/sti-model/element_spec.rb +24 -24
- data/spec/sti-model/vehicle_spec.rb +6 -6
- data/spec/support/active_record.rb +28 -5
- data/spec/support/database.yml +9 -17
- metadata +67 -44
data/lib/ranked-model/version.rb
CHANGED
data/ranked-model.gemspec
CHANGED
@@ -9,17 +9,18 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Matthew Beale"]
|
10
10
|
s.email = ["matt.beale@madhatted.com"]
|
11
11
|
s.homepage = "https://github.com/mixonic/ranked-model"
|
12
|
-
s.summary = %q{An acts_as_sortable replacement built for Rails
|
13
|
-
s.description = %q{ranked-model is a modern row sorting library built for Rails
|
12
|
+
s.summary = %q{An acts_as_sortable replacement built for Rails 4.2+}
|
13
|
+
s.description = %q{ranked-model is a modern row sorting library built for Rails 4.2+. It uses ARel aggressively and is better optimized than most other libraries.}
|
14
14
|
s.license = 'MIT'
|
15
15
|
|
16
|
-
s.add_dependency "activerecord", ">=
|
17
|
-
s.add_development_dependency "rspec", "~>
|
18
|
-
s.add_development_dependency "
|
19
|
-
s.add_development_dependency "
|
20
|
-
s.add_development_dependency "
|
21
|
-
s.add_development_dependency "database_cleaner", "~> 1.2.0"
|
16
|
+
s.add_dependency "activerecord", ">= 4.2"
|
17
|
+
s.add_development_dependency "rspec", "~> 3"
|
18
|
+
s.add_development_dependency "rspec-its"
|
19
|
+
s.add_development_dependency "mocha"
|
20
|
+
s.add_development_dependency "database_cleaner", "~> 1.7.0"
|
22
21
|
s.add_development_dependency "rake", "~> 10.1.0"
|
22
|
+
s.add_development_dependency "appraisal"
|
23
|
+
s.add_development_dependency "pry"
|
23
24
|
|
24
25
|
s.files = `git ls-files`.split("\n")
|
25
26
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'ColumnDefaultDuck' do
|
4
|
+
|
5
|
+
it "should raise an error if we try to initialise ranked_model on a column with a default value" do
|
6
|
+
expect {
|
7
|
+
class ColumnDefaultDuck < ActiveRecord::Base
|
8
|
+
include RankedModel
|
9
|
+
ranks :size, :with_same => :pond
|
10
|
+
end
|
11
|
+
}.to raise_error(RankedModel::NonNilColumnDefault, 'Your ranked model column "size" must not have a default value in the database.')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should not raise an error if we don't have a database connection when checking for default value" do
|
15
|
+
begin
|
16
|
+
ActiveRecord::Base.remove_connection
|
17
|
+
|
18
|
+
expect {
|
19
|
+
class ColumnDefaultDuck < ActiveRecord::Base
|
20
|
+
include RankedModel
|
21
|
+
ranks :size, :with_same => :pond
|
22
|
+
end
|
23
|
+
}.not_to raise_error
|
24
|
+
ensure
|
25
|
+
ActiveRecord::Base.establish_connection(ENV['DB'].to_sym)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -8,14 +8,18 @@ describe Duck do
|
|
8
8
|
|
9
9
|
subject { @duck }
|
10
10
|
|
11
|
-
it { subject.respond_to
|
12
|
-
it { subject.respond_to
|
13
|
-
it { subject.respond_to
|
14
|
-
it { subject.respond_to
|
15
|
-
it { subject.respond_to
|
16
|
-
it { subject.respond_to
|
17
|
-
it { subject.respond_to
|
18
|
-
it { subject.respond_to
|
11
|
+
it { expect(subject).to respond_to(:row_position) }
|
12
|
+
it { expect(subject).to respond_to(:row_position=) }
|
13
|
+
it { expect(subject).to respond_to(:row_rank) }
|
14
|
+
it { expect(subject).to respond_to(:size_position) }
|
15
|
+
it { expect(subject).to respond_to(:size_position=) }
|
16
|
+
it { expect(subject).to respond_to(:size_rank) }
|
17
|
+
it { expect(subject).to respond_to(:age_position) }
|
18
|
+
it { expect(subject).to respond_to(:age_position=) }
|
19
|
+
it { expect(subject).to respond_to(:age_rank) }
|
20
|
+
it { expect(subject).to respond_to(:landing_order_position) }
|
21
|
+
it { expect(subject).to respond_to(:landing_order_position=) }
|
22
|
+
it { expect(subject).to respond_to(:landing_order_rank) }
|
19
23
|
|
20
24
|
end
|
21
25
|
|
@@ -44,9 +48,9 @@ describe Duck do
|
|
44
48
|
}
|
45
49
|
@ducks.each { |name, duck|
|
46
50
|
duck.reload
|
47
|
-
duck.
|
48
|
-
duck.
|
49
|
-
duck.
|
51
|
+
duck.update :row_position => 0
|
52
|
+
duck.update :size_position => 0
|
53
|
+
duck.update :age_position => 0
|
50
54
|
duck.save!
|
51
55
|
}
|
52
56
|
@ducks.each {|name, duck| duck.reload }
|
@@ -55,8 +59,8 @@ describe Duck do
|
|
55
59
|
describe "sorting by size on in_shin_pond" do
|
56
60
|
|
57
61
|
before {
|
58
|
-
@ducks[:quacky].
|
59
|
-
@ducks[:wingy].
|
62
|
+
@ducks[:quacky].update :size_position => 0
|
63
|
+
@ducks[:wingy].update :size_position => 2
|
60
64
|
}
|
61
65
|
|
62
66
|
subject { Duck.in_shin_pond.rank(:size).to_a }
|
@@ -72,8 +76,8 @@ describe Duck do
|
|
72
76
|
describe "sorting by age on Shin pond" do
|
73
77
|
|
74
78
|
before {
|
75
|
-
@ducks[:feathers].
|
76
|
-
@ducks[:wingy].
|
79
|
+
@ducks[:feathers].update :age_position => 0
|
80
|
+
@ducks[:wingy].update :age_position => 0
|
77
81
|
}
|
78
82
|
|
79
83
|
subject { Duck.where(:pond => 'Shin').rank(:age).to_a }
|
@@ -89,10 +93,10 @@ describe Duck do
|
|
89
93
|
describe "sorting by row" do
|
90
94
|
|
91
95
|
before {
|
92
|
-
@ducks[:beaky].
|
93
|
-
@ducks[:webby].
|
94
|
-
@ducks[:waddly].
|
95
|
-
@ducks[:wingy].
|
96
|
+
@ducks[:beaky].update :row_position => 0
|
97
|
+
@ducks[:webby].update :row_position => 2
|
98
|
+
@ducks[:waddly].update :row_position => 2
|
99
|
+
@ducks[:wingy].update :row_position => 6
|
96
100
|
}
|
97
101
|
|
98
102
|
subject { Duck.rank(:row).to_a }
|
@@ -108,13 +112,13 @@ describe Duck do
|
|
108
112
|
describe "mixed sorting by" do
|
109
113
|
|
110
114
|
before {
|
111
|
-
@ducks[:quacky].
|
112
|
-
@ducks[:beaky].
|
113
|
-
@ducks[:webby].
|
114
|
-
@ducks[:wingy].
|
115
|
-
@ducks[:waddly].
|
116
|
-
@ducks[:wingy].
|
117
|
-
@ducks[:webby].
|
115
|
+
@ducks[:quacky].update :size_position => 0
|
116
|
+
@ducks[:beaky].update :row_position => 0
|
117
|
+
@ducks[:webby].update :row_position => 2
|
118
|
+
@ducks[:wingy].update :size_position => 1
|
119
|
+
@ducks[:waddly].update :row_position => 2
|
120
|
+
@ducks[:wingy].update :row_position => 6
|
121
|
+
@ducks[:webby].update :row_position => 6
|
118
122
|
}
|
119
123
|
|
120
124
|
describe "row" do
|
@@ -148,9 +152,9 @@ describe Duck do
|
|
148
152
|
it "doesn't change ranking" do
|
149
153
|
# puts Duck.rank(:age).collect {|duck| "#{duck.name} #{duck.age}" }
|
150
154
|
duck = Duck.rank(:age)[2]
|
151
|
-
->{
|
152
|
-
duck.
|
153
|
-
}.
|
155
|
+
expect(->{
|
156
|
+
duck.update :name => 'New Name'
|
157
|
+
}).to_not change(duck.reload, :age)
|
154
158
|
# puts Duck.rank(:age).collect {|duck| "#{duck.name} #{duck.age}" }
|
155
159
|
end
|
156
160
|
|
@@ -161,7 +165,7 @@ describe Duck do
|
|
161
165
|
it "marks record as changed" do
|
162
166
|
duck = Duck.rank(:age)[2]
|
163
167
|
duck.age_position = 1
|
164
|
-
duck.changed
|
168
|
+
expect(duck.changed?).to be true
|
165
169
|
end
|
166
170
|
|
167
171
|
end
|
@@ -172,7 +176,7 @@ describe Duck do
|
|
172
176
|
|
173
177
|
it "doesnt set empty string" do
|
174
178
|
subject.age_position = ''
|
175
|
-
subject.age_position.
|
179
|
+
expect(subject.age_position).to be_nil
|
176
180
|
end
|
177
181
|
|
178
182
|
end
|
@@ -183,7 +187,7 @@ describe Duck do
|
|
183
187
|
|
184
188
|
before {
|
185
189
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
|
186
|
-
@ducks[:wingy].
|
190
|
+
@ducks[:wingy].update :row_position => 2
|
187
191
|
}
|
188
192
|
|
189
193
|
context {
|
@@ -198,9 +202,9 @@ describe Duck do
|
|
198
202
|
|
199
203
|
subject { Duck.rank(:row).collect {|duck| duck.id } }
|
200
204
|
|
201
|
-
it { subject[0..1].
|
205
|
+
it { expect(subject[0..1]).to eq(@ordered[0..1]) }
|
202
206
|
|
203
|
-
it { subject[3..subject.length].
|
207
|
+
it { expect(subject[3..subject.length]).to eq(@ordered[2..@ordered.length]) }
|
204
208
|
|
205
209
|
}
|
206
210
|
|
@@ -210,7 +214,7 @@ describe Duck do
|
|
210
214
|
|
211
215
|
before {
|
212
216
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
|
213
|
-
@ducks[:wingy].
|
217
|
+
@ducks[:wingy].update :row_position => 0
|
214
218
|
}
|
215
219
|
|
216
220
|
context {
|
@@ -233,7 +237,38 @@ describe Duck do
|
|
233
237
|
|
234
238
|
subject { Duck.rank(:row).collect {|duck| duck.id } }
|
235
239
|
|
236
|
-
it { subject[1..subject.length].
|
240
|
+
it { expect(subject[1..subject.length]).to eq(@ordered) }
|
241
|
+
|
242
|
+
}
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
describe "second to last" do
|
247
|
+
|
248
|
+
before {
|
249
|
+
[:quacky, :feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
|
250
|
+
Duck.where(id: @ducks[name].id).update_all(row: RankedModel::MAX_RANK_VALUE - i)
|
251
|
+
@ducks[name].reload
|
252
|
+
end
|
253
|
+
}
|
254
|
+
|
255
|
+
context {
|
256
|
+
|
257
|
+
before { @ducks[:wingy].update :row_position => (@ducks.size - 2) }
|
258
|
+
|
259
|
+
subject { Duck.ranker(:row).with(Duck.new).current_at_position(@ducks.size - 2).instance }
|
260
|
+
|
261
|
+
its(:id) { should == @ducks[:wingy].id }
|
262
|
+
|
263
|
+
}
|
264
|
+
|
265
|
+
context {
|
266
|
+
|
267
|
+
before { @ducks[:wingy].update :row_position => :down }
|
268
|
+
|
269
|
+
subject { Duck.ranker(:row).with(Duck.new).current_at_position(@ducks.size - 2).instance }
|
270
|
+
|
271
|
+
its(:id) { should == @ducks[:wingy].id }
|
237
272
|
|
238
273
|
}
|
239
274
|
|
@@ -243,7 +278,7 @@ describe Duck do
|
|
243
278
|
|
244
279
|
before {
|
245
280
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
|
246
|
-
@ducks[:wingy].
|
281
|
+
@ducks[:wingy].update :row_position => (@ducks.size - 1)
|
247
282
|
}
|
248
283
|
|
249
284
|
context {
|
@@ -274,7 +309,7 @@ describe Duck do
|
|
274
309
|
|
275
310
|
subject { Duck.rank(:row).collect {|duck| duck.id } }
|
276
311
|
|
277
|
-
it { subject[0..-2].
|
312
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
278
313
|
|
279
314
|
}
|
280
315
|
|
@@ -284,7 +319,7 @@ describe Duck do
|
|
284
319
|
|
285
320
|
before {
|
286
321
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
|
287
|
-
@ducks[:wingy].
|
322
|
+
@ducks[:wingy].update :row_position => :last
|
288
323
|
}
|
289
324
|
|
290
325
|
context {
|
@@ -315,7 +350,7 @@ describe Duck do
|
|
315
350
|
|
316
351
|
subject { Duck.rank(:row).collect {|duck| duck.id } }
|
317
352
|
|
318
|
-
it { subject[0..-2].
|
353
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
319
354
|
|
320
355
|
}
|
321
356
|
|
@@ -325,7 +360,7 @@ describe Duck do
|
|
325
360
|
|
326
361
|
before {
|
327
362
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect {|duck| duck.id }
|
328
|
-
@ducks[:wingy].
|
363
|
+
@ducks[:wingy].update :row_position => 'last'
|
329
364
|
}
|
330
365
|
|
331
366
|
context {
|
@@ -356,7 +391,7 @@ describe Duck do
|
|
356
391
|
|
357
392
|
subject { Duck.rank(:row).collect {|duck| duck.id } }
|
358
393
|
|
359
|
-
it { subject[0..-2].
|
394
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
360
395
|
|
361
396
|
}
|
362
397
|
|
@@ -368,7 +403,7 @@ describe Duck do
|
|
368
403
|
|
369
404
|
before {
|
370
405
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
|
371
|
-
@ducks[:wingy].
|
406
|
+
@ducks[:wingy].update :row_position => :down
|
372
407
|
}
|
373
408
|
|
374
409
|
context {
|
@@ -383,9 +418,9 @@ describe Duck do
|
|
383
418
|
|
384
419
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
385
420
|
|
386
|
-
it { subject[0..3].
|
421
|
+
it { expect(subject[0..3]).to eq(@ordered[0..3]) }
|
387
422
|
|
388
|
-
it { subject[5..subject.length].
|
423
|
+
it { expect(subject[5..subject.length]).to eq(@ordered[4..@ordered.length]) }
|
389
424
|
|
390
425
|
}
|
391
426
|
|
@@ -395,7 +430,7 @@ describe Duck do
|
|
395
430
|
|
396
431
|
before {
|
397
432
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:quacky].id).collect { |duck| duck.id }
|
398
|
-
@ducks[:quacky].
|
433
|
+
@ducks[:quacky].update :row_position => :down
|
399
434
|
}
|
400
435
|
|
401
436
|
context {
|
@@ -410,7 +445,7 @@ describe Duck do
|
|
410
445
|
|
411
446
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
412
447
|
|
413
|
-
it { subject[0..-2].
|
448
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
414
449
|
|
415
450
|
}
|
416
451
|
|
@@ -420,7 +455,7 @@ describe Duck do
|
|
420
455
|
|
421
456
|
before {
|
422
457
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:feathers].id).collect { |duck| duck.id }
|
423
|
-
@ducks[:feathers].
|
458
|
+
@ducks[:feathers].update :row_position => :down
|
424
459
|
}
|
425
460
|
|
426
461
|
context {
|
@@ -435,7 +470,7 @@ describe Duck do
|
|
435
470
|
|
436
471
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
437
472
|
|
438
|
-
it { subject[0..-2].
|
473
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
439
474
|
|
440
475
|
}
|
441
476
|
|
@@ -449,7 +484,7 @@ describe Duck do
|
|
449
484
|
|
450
485
|
before {
|
451
486
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
|
452
|
-
@ducks[:wingy].
|
487
|
+
@ducks[:wingy].update :row_position => 'down'
|
453
488
|
}
|
454
489
|
|
455
490
|
context {
|
@@ -464,9 +499,9 @@ describe Duck do
|
|
464
499
|
|
465
500
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
466
501
|
|
467
|
-
it { subject[0..3].
|
502
|
+
it { expect(subject[0..3]).to eq(@ordered[0..3]) }
|
468
503
|
|
469
|
-
it { subject[5..subject.length].
|
504
|
+
it { expect(subject[5..subject.length]).to eq(@ordered[4..@ordered.length]) }
|
470
505
|
|
471
506
|
}
|
472
507
|
|
@@ -476,7 +511,7 @@ describe Duck do
|
|
476
511
|
|
477
512
|
before {
|
478
513
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:quacky].id).collect { |duck| duck.id }
|
479
|
-
@ducks[:quacky].
|
514
|
+
@ducks[:quacky].update :row_position => 'down'
|
480
515
|
}
|
481
516
|
|
482
517
|
context {
|
@@ -491,7 +526,7 @@ describe Duck do
|
|
491
526
|
|
492
527
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
493
528
|
|
494
|
-
it { subject[0..-2].
|
529
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
495
530
|
|
496
531
|
}
|
497
532
|
|
@@ -501,7 +536,7 @@ describe Duck do
|
|
501
536
|
|
502
537
|
before {
|
503
538
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:feathers].id).collect { |duck| duck.id }
|
504
|
-
@ducks[:feathers].
|
539
|
+
@ducks[:feathers].update :row_position => 'down'
|
505
540
|
}
|
506
541
|
|
507
542
|
context {
|
@@ -516,7 +551,7 @@ describe Duck do
|
|
516
551
|
|
517
552
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
518
553
|
|
519
|
-
it { subject[0..-2].
|
554
|
+
it { expect(subject[0..-2]).to eq(@ordered) }
|
520
555
|
|
521
556
|
}
|
522
557
|
|
@@ -530,7 +565,7 @@ describe Duck do
|
|
530
565
|
|
531
566
|
before {
|
532
567
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
|
533
|
-
@ducks[:wingy].
|
568
|
+
@ducks[:wingy].update :row_position => :up
|
534
569
|
}
|
535
570
|
|
536
571
|
context {
|
@@ -545,9 +580,9 @@ describe Duck do
|
|
545
580
|
|
546
581
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
547
582
|
|
548
|
-
it { subject[0..1].
|
583
|
+
it { expect(subject[0..1]).to eq(@ordered[0..1]) }
|
549
584
|
|
550
|
-
it { subject[3..subject.length].
|
585
|
+
it { expect(subject[3..subject.length]).to eq(@ordered[2..@ordered.length]) }
|
551
586
|
|
552
587
|
}
|
553
588
|
|
@@ -557,7 +592,7 @@ describe Duck do
|
|
557
592
|
|
558
593
|
before {
|
559
594
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:beaky].id).collect { |duck| duck.id }
|
560
|
-
@ducks[:beaky].
|
595
|
+
@ducks[:beaky].update :row_position => :up
|
561
596
|
}
|
562
597
|
|
563
598
|
context {
|
@@ -572,7 +607,7 @@ describe Duck do
|
|
572
607
|
|
573
608
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
574
609
|
|
575
|
-
it { subject[1..subject.length].
|
610
|
+
it { expect(subject[1..subject.length]).to eq(@ordered) }
|
576
611
|
|
577
612
|
}
|
578
613
|
|
@@ -582,7 +617,7 @@ describe Duck do
|
|
582
617
|
|
583
618
|
before {
|
584
619
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:waddly].id).collect { |duck| duck.id }
|
585
|
-
@ducks[:waddly].
|
620
|
+
@ducks[:waddly].update :row_position => :up
|
586
621
|
}
|
587
622
|
|
588
623
|
context {
|
@@ -597,12 +632,41 @@ describe Duck do
|
|
597
632
|
|
598
633
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
599
634
|
|
600
|
-
it { subject[1..subject.length].
|
635
|
+
it { expect(subject[1..subject.length]).to eq(@ordered) }
|
636
|
+
|
637
|
+
}
|
638
|
+
|
639
|
+
end
|
640
|
+
|
641
|
+
context "from position without gaps with rebalance" do
|
642
|
+
|
643
|
+
before {
|
644
|
+
[:quacky, :feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
|
645
|
+
Duck.where(id: @ducks[name].id).update_all(row: i)
|
646
|
+
@ducks[name].reload
|
647
|
+
end
|
648
|
+
@ducks[:wingy].update :row_position => :up
|
649
|
+
}
|
650
|
+
|
651
|
+
context {
|
652
|
+
|
653
|
+
subject { Duck.ranker(:row).with(Duck.new).current_at_position(1).instance }
|
654
|
+
|
655
|
+
its(:id) { should == @ducks[:wingy].id }
|
656
|
+
|
657
|
+
}
|
658
|
+
|
659
|
+
context {
|
660
|
+
|
661
|
+
subject { Duck.ranker(:row).with(Duck.new).current_at_position(2).instance }
|
662
|
+
|
663
|
+
its(:id) { should == @ducks[:feathers].id }
|
601
664
|
|
602
665
|
}
|
603
666
|
|
604
667
|
end
|
605
668
|
|
669
|
+
|
606
670
|
end
|
607
671
|
|
608
672
|
describe "up with string" do
|
@@ -611,7 +675,7 @@ describe Duck do
|
|
611
675
|
|
612
676
|
before {
|
613
677
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:wingy].id).collect { |duck| duck.id }
|
614
|
-
@ducks[:wingy].
|
678
|
+
@ducks[:wingy].update :row_position => 'up'
|
615
679
|
}
|
616
680
|
|
617
681
|
context {
|
@@ -626,9 +690,9 @@ describe Duck do
|
|
626
690
|
|
627
691
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
628
692
|
|
629
|
-
it { subject[0..1].
|
693
|
+
it { expect(subject[0..1]).to eq(@ordered[0..1]) }
|
630
694
|
|
631
|
-
it { subject[3..subject.length].
|
695
|
+
it { expect(subject[3..subject.length]).to eq(@ordered[2..@ordered.length]) }
|
632
696
|
|
633
697
|
}
|
634
698
|
|
@@ -638,7 +702,7 @@ describe Duck do
|
|
638
702
|
|
639
703
|
before {
|
640
704
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:beaky].id).collect { |duck| duck.id }
|
641
|
-
@ducks[:beaky].
|
705
|
+
@ducks[:beaky].update :row_position => 'up'
|
642
706
|
}
|
643
707
|
|
644
708
|
context {
|
@@ -653,7 +717,7 @@ describe Duck do
|
|
653
717
|
|
654
718
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
655
719
|
|
656
|
-
it { subject[1..subject.length].
|
720
|
+
it { expect(subject[1..subject.length]).to eq(@ordered) }
|
657
721
|
|
658
722
|
}
|
659
723
|
|
@@ -663,7 +727,7 @@ describe Duck do
|
|
663
727
|
|
664
728
|
before {
|
665
729
|
@ordered = Duck.rank(:row).where(Duck.arel_table[:id].not_eq @ducks[:waddly].id).collect { |duck| duck.id }
|
666
|
-
@ducks[:waddly].
|
730
|
+
@ducks[:waddly].update :row_position => 'up'
|
667
731
|
}
|
668
732
|
|
669
733
|
context {
|
@@ -678,7 +742,7 @@ describe Duck do
|
|
678
742
|
|
679
743
|
subject { Duck.rank(:row).collect { |duck| duck.id } }
|
680
744
|
|
681
|
-
it { subject[1..subject.length].
|
745
|
+
it { expect(subject[1..subject.length]).to eq(@ordered) }
|
682
746
|
|
683
747
|
}
|
684
748
|
|
@@ -688,6 +752,71 @@ describe Duck do
|
|
688
752
|
|
689
753
|
end
|
690
754
|
|
755
|
+
describe "fetching rank for an instance" do
|
756
|
+
before {
|
757
|
+
[:quacky, :feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
|
758
|
+
Duck.where(id: @ducks[name].id).update_all(row: RankedModel::MAX_RANK_VALUE - i)
|
759
|
+
@ducks[name].reload
|
760
|
+
end
|
761
|
+
}
|
762
|
+
|
763
|
+
context {
|
764
|
+
subject { Duck.find_by(id: @ducks[:beaky]).row_rank }
|
765
|
+
|
766
|
+
it { should == 0 }
|
767
|
+
}
|
768
|
+
|
769
|
+
context {
|
770
|
+
subject { Duck.find_by(id: @ducks[:wingy]).row_rank }
|
771
|
+
|
772
|
+
it { should == 3 }
|
773
|
+
}
|
774
|
+
|
775
|
+
context {
|
776
|
+
subject { Duck.find_by(id: @ducks[:quacky]).row_rank }
|
777
|
+
|
778
|
+
it { should == 5 }
|
779
|
+
}
|
780
|
+
end
|
781
|
+
|
782
|
+
describe "when moving between ponds should work when rebalancing" do
|
783
|
+
before do
|
784
|
+
[:feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
|
785
|
+
Duck.where(id: @ducks[name].id)
|
786
|
+
.update_all(age: RankedModel::MIN_RANK_VALUE + i, pond: "Boyden")
|
787
|
+
end
|
788
|
+
|
789
|
+
@ducks[:quacky].update!(age_position: 2, pond: "Boyden")
|
790
|
+
end
|
791
|
+
|
792
|
+
it 'rebalances ranks correctly' do
|
793
|
+
expect(@ducks[:feathers].reload.age_rank).to eq 0
|
794
|
+
expect(@ducks[:quacky].reload.age_rank).to eq 2
|
795
|
+
expect(@ducks[:beaky].reload.age_rank).to eq 5
|
796
|
+
end
|
797
|
+
|
798
|
+
context 'when attempting to update position to a non-unique value' do
|
799
|
+
before do
|
800
|
+
@duck_one = Duck.create(landing_order: RankedModel::MIN_RANK_VALUE,
|
801
|
+
lake_id: 42, flock_id: 42)
|
802
|
+
# Duck one's landing order will be rebalanced to -715_827_883.
|
803
|
+
# Given a unique index on [:landing_order, :lake_id, :flock_id] we
|
804
|
+
# verify that the operation succeeds despite the value already being
|
805
|
+
# occupied by duck two.
|
806
|
+
@duck_two = Duck.create(landing_order: -715_827_883,
|
807
|
+
lake_id: 42, flock_id: 42)
|
808
|
+
end
|
809
|
+
|
810
|
+
it 'rebalances ranks correctly' do
|
811
|
+
@ducks[:quacky].update!(landing_order_position: :first,
|
812
|
+
lake_id: 42, flock_id: 42)
|
813
|
+
expect(@ducks[:quacky].reload.landing_order_rank).to eq 0
|
814
|
+
expect(@duck_one.reload.landing_order_rank).to eq 1
|
815
|
+
expect(@duck_two.reload.landing_order_rank).to eq 2
|
816
|
+
end
|
817
|
+
end
|
818
|
+
end
|
819
|
+
|
691
820
|
end
|
692
821
|
|
693
822
|
describe Duck do
|
@@ -721,7 +850,7 @@ describe Duck do
|
|
721
850
|
}
|
722
851
|
@ducks.each { |name, duck|
|
723
852
|
duck.reload
|
724
|
-
duck.
|
853
|
+
duck.update :landing_order_position => 0
|
725
854
|
duck.save!
|
726
855
|
}
|
727
856
|
@ducks.each {|name, duck| duck.reload }
|
@@ -730,8 +859,8 @@ describe Duck do
|
|
730
859
|
describe "sorting by landing_order" do
|
731
860
|
|
732
861
|
before {
|
733
|
-
@ducks[:quacky].
|
734
|
-
@ducks[:wingy].
|
862
|
+
@ducks[:quacky].update :landing_order_position => 0
|
863
|
+
@ducks[:wingy].update :landing_order_position => 1
|
735
864
|
}
|
736
865
|
|
737
866
|
subject { Duck.in_lake_and_flock(0,0).rank(:landing_order).to_a }
|
@@ -755,15 +884,15 @@ describe Duck do
|
|
755
884
|
|
756
885
|
@previous_ranks = @untouchable_ranks.call
|
757
886
|
|
758
|
-
@ducks[:quacky].
|
759
|
-
@ducks[:wingy].
|
760
|
-
@ducks[:feathers].
|
761
|
-
@ducks[:wingy].
|
887
|
+
@ducks[:quacky].update :landing_order_position => 0
|
888
|
+
@ducks[:wingy].update :landing_order_position => 1
|
889
|
+
@ducks[:feathers].update :landing_order_position => 0
|
890
|
+
@ducks[:wingy].update :landing_order_position => 1
|
762
891
|
}
|
763
892
|
|
764
893
|
subject { @untouchable_ranks.call }
|
765
894
|
|
766
|
-
it {
|
895
|
+
it { is_expected.to eq(@previous_ranks) }
|
767
896
|
|
768
897
|
end
|
769
898
|
|