positionable 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/positionable.rb +5 -13
- data/lib/positionable/version.rb +1 -1
- data/positionable.gemspec +1 -1
- data/spec/lib/positionable_spec.rb +54 -52
- data/spec/spec_helper.rb +1 -0
- data/spec/support/matchers/contiguity_matcher.rb +1 -0
- metadata +6 -5
data/lib/positionable.rb
CHANGED
@@ -251,19 +251,15 @@ module Positionable
|
|
251
251
|
# Reorders records between provided positions, unless the destination position is out of range.
|
252
252
|
def reorder(from, to)
|
253
253
|
if to > from
|
254
|
-
shift,
|
254
|
+
shift, positions_range = -1, ((from + 1)..to)
|
255
255
|
elsif scope_changed?
|
256
256
|
# When scope changes, it actually inserts this record in the new scope
|
257
257
|
# All next siblings (from new position to bottom) have to be staggered
|
258
|
-
shift,
|
258
|
+
shift, positions_range = 1, (to..bottom)
|
259
259
|
else
|
260
|
-
shift,
|
261
|
-
end
|
262
|
-
self.class.transaction do
|
263
|
-
siblings.map do |sibling|
|
264
|
-
sibling.update_column(:position, sibling.position + shift)
|
265
|
-
end
|
260
|
+
shift, positions_range = 1, (to..(from - 1))
|
266
261
|
end
|
262
|
+
scoped_all.where(position: positions_range).update_all(['position = position + ?', shift])
|
267
263
|
end
|
268
264
|
|
269
265
|
# Reorders records between old and new position (and old and new scope).
|
@@ -296,11 +292,7 @@ module Positionable
|
|
296
292
|
|
297
293
|
# Decrements the position of all the provided records.
|
298
294
|
def decrement(records)
|
299
|
-
|
300
|
-
records.each do |record|
|
301
|
-
record.update_column(:position, record.position - 1)
|
302
|
-
end
|
303
|
-
end
|
295
|
+
records.update_all(['position = position - 1'])
|
304
296
|
end
|
305
297
|
|
306
298
|
end
|
data/lib/positionable/version.rb
CHANGED
data/positionable.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.email = ["philippe.guegan@gmail.com"]
|
10
10
|
s.homepage = "https://github.com/pguegan/positionable"
|
11
11
|
s.summary = %q(A gem for positionning your ActiveRecord models.)
|
12
|
-
s.description = %q(This extension provides contiguous positionning capabilities to
|
12
|
+
s.description = %q(This extension provides contiguous positionning capabilities to your ActiveRecord models.)
|
13
13
|
|
14
14
|
s.rubyforge_project = "positionable"
|
15
15
|
|
@@ -49,7 +49,7 @@ describe Positionable do
|
|
49
49
|
it "orders records by their position by default" do
|
50
50
|
shuffle_positions = (0..9).to_a.shuffle
|
51
51
|
shuffle_positions.each do |position|
|
52
|
-
item =
|
52
|
+
item = create(:default_item)
|
53
53
|
item.update_column(:position, position)
|
54
54
|
end
|
55
55
|
DefaultItem.all.should be_contiguous.starting_at(0)
|
@@ -59,7 +59,7 @@ describe Positionable do
|
|
59
59
|
|
60
60
|
context "contiguous positionning" do
|
61
61
|
|
62
|
-
let!(:items) {
|
62
|
+
let!(:items) { create_list(:default_item, 10) }
|
63
63
|
let(:middle) { items[items.size / 2] }
|
64
64
|
|
65
65
|
it "makes the position to start at zero by default" do
|
@@ -67,7 +67,7 @@ describe Positionable do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
it "increments position by one after creation" do
|
70
|
-
item =
|
70
|
+
item = create(:default_item)
|
71
71
|
item.position.should == items.last.position + 1
|
72
72
|
end
|
73
73
|
|
@@ -106,17 +106,17 @@ describe Positionable do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
it "caracterizes the first record" do
|
109
|
-
items.first.
|
109
|
+
items.first.should be_first
|
110
110
|
items.but_first.each do |item|
|
111
|
-
item.
|
111
|
+
item.should_not be_first
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
115
|
it "caracterizes the last record" do
|
116
116
|
items.but_last.each do |item|
|
117
|
-
item.
|
117
|
+
item.should_not be_last
|
118
118
|
end
|
119
|
-
items.last.
|
119
|
+
items.last.should be_last
|
120
120
|
end
|
121
121
|
|
122
122
|
it "decrements positions of next sibblings after deletion" do
|
@@ -167,9 +167,9 @@ describe Positionable do
|
|
167
167
|
context "inheritance" do
|
168
168
|
|
169
169
|
it "inserts contiguously records of all subclasses" do
|
170
|
-
|
171
|
-
|
172
|
-
|
170
|
+
create(:sub_item_1).position.should == items.count
|
171
|
+
create(:sub_item_2).position.should == items.count + 1
|
172
|
+
create(:sub_item_1).position.should == items.count + 2
|
173
173
|
end
|
174
174
|
|
175
175
|
end
|
@@ -256,10 +256,10 @@ describe Positionable do
|
|
256
256
|
|
257
257
|
describe "range" do
|
258
258
|
|
259
|
-
let!(:items) {
|
259
|
+
let!(:items) { create_list(:default_item, 10) }
|
260
260
|
|
261
261
|
it "gives the range position of a new record" do
|
262
|
-
item =
|
262
|
+
item = build(:default_item)
|
263
263
|
item.range.should == (0..items.count)
|
264
264
|
end
|
265
265
|
|
@@ -271,7 +271,7 @@ describe Positionable do
|
|
271
271
|
|
272
272
|
context "scoping" do
|
273
273
|
|
274
|
-
let!(:folders) {
|
274
|
+
let!(:folders) { create_list(:folder_with_documents, 5) }
|
275
275
|
|
276
276
|
it "orders records by their position by default" do
|
277
277
|
folders.each do |folder|
|
@@ -294,7 +294,7 @@ describe Positionable do
|
|
294
294
|
it "increments position by one after creation inside a folder" do
|
295
295
|
folders.each do |folder|
|
296
296
|
last_position = folder.documents.last.position
|
297
|
-
document =
|
297
|
+
document = create(:document, :folder => folder)
|
298
298
|
document.position.should == last_position + 1
|
299
299
|
end
|
300
300
|
end
|
@@ -353,9 +353,9 @@ describe Positionable do
|
|
353
353
|
it "caracterizes the first record of the folder" do
|
354
354
|
folders.each do |folder|
|
355
355
|
documents = folder.documents
|
356
|
-
documents.first.
|
356
|
+
documents.first.should be_first
|
357
357
|
documents.but_first.each do |document|
|
358
|
-
document.
|
358
|
+
document.should_not be_first
|
359
359
|
end
|
360
360
|
end
|
361
361
|
end
|
@@ -364,9 +364,9 @@ describe Positionable do
|
|
364
364
|
folders.each do |folder|
|
365
365
|
documents = folder.documents
|
366
366
|
documents.but_last.each do |document|
|
367
|
-
document.
|
367
|
+
document.should_not be_last
|
368
368
|
end
|
369
|
-
documents.last.
|
369
|
+
documents.last.should be_last
|
370
370
|
end
|
371
371
|
end
|
372
372
|
|
@@ -438,19 +438,23 @@ describe Positionable do
|
|
438
438
|
# Last document is a special case when changing scope, so it is avoided
|
439
439
|
let!(:document) { old_folder.documents.but_last.sample }
|
440
440
|
# A new folder containing a different count of documents than the old folder
|
441
|
-
let!(:new_folder) {
|
442
|
-
let!(:new_documents) {
|
441
|
+
let!(:new_folder) { create(:folder) }
|
442
|
+
let!(:new_documents) { create_list(:document, old_folder.documents.count + 1, :folder => new_folder) }
|
443
443
|
|
444
444
|
it "moves to bottom position when scope has changed but position is out of range" do
|
445
445
|
document.update_attributes( {:folder_id => new_folder.id, :position => new_documents.count + 10 } )
|
446
446
|
document.position.should == new_folder.documents.count - 1
|
447
|
-
document.
|
447
|
+
document.should be_last
|
448
448
|
end
|
449
449
|
|
450
450
|
it "keeps position when scope has changed but position belongs to range" do
|
451
|
-
|
451
|
+
lambda {
|
452
|
+
document.update_attributes( {:folder_id => new_folder.id} )
|
453
|
+
}.should_not change(document, :position)
|
454
|
+
end
|
455
|
+
|
456
|
+
it "reorders records of target scope" do
|
452
457
|
document.update_attributes( {:folder_id => new_folder.id} )
|
453
|
-
document.position.should == position # Position unchanged
|
454
458
|
new_folder.reload.documents.should be_contiguous.starting_at(0)
|
455
459
|
end
|
456
460
|
|
@@ -472,27 +476,27 @@ describe Positionable do
|
|
472
476
|
end
|
473
477
|
|
474
478
|
it "gives the range within a scope" do
|
475
|
-
folder =
|
479
|
+
folder = create(:folder_with_documents)
|
476
480
|
document = Document.new
|
477
481
|
document.range(folder).should == (0..folder.documents.count)
|
478
482
|
end
|
479
483
|
|
480
484
|
it "gives the range within its own scope by default" do
|
481
|
-
folder =
|
485
|
+
folder = create(:folder_with_documents)
|
482
486
|
document = folder.documents.sample
|
483
487
|
document.range.should == (0..(folder.documents.count - 1))
|
484
488
|
end
|
485
489
|
|
486
490
|
it "gives the range within another scope" do
|
487
|
-
document =
|
488
|
-
folder =
|
491
|
+
document = build(:document)
|
492
|
+
folder = create(:folder_with_documents)
|
489
493
|
document.folder.should_not == folder # Meta!
|
490
494
|
document.range(folder).should == (0..folder.documents.count)
|
491
495
|
end
|
492
496
|
|
493
497
|
it "gives the range within another empty scope" do
|
494
|
-
document =
|
495
|
-
folder =
|
498
|
+
document = build(:document)
|
499
|
+
folder = create(:folder)
|
496
500
|
document.folder.should_not == folder # Meta!
|
497
501
|
folder.documents.should be_empty # Meta!
|
498
502
|
document.range(folder).should == (0..0)
|
@@ -503,14 +507,14 @@ describe Positionable do
|
|
503
507
|
context "existing record" do
|
504
508
|
|
505
509
|
it "gives the range within its own scope" do
|
506
|
-
folder =
|
510
|
+
folder = create(:folder_with_documents)
|
507
511
|
document = folder.documents.sample
|
508
512
|
document.range(folder).should == (0..(folder.documents.count - 1))
|
509
513
|
end
|
510
514
|
|
511
515
|
it "gives the range within another scope" do
|
512
|
-
document =
|
513
|
-
folder =
|
516
|
+
document = create(:document)
|
517
|
+
folder = create(:folder_with_documents)
|
514
518
|
document.folder.should_not == folder # Meta!
|
515
519
|
document.range(folder).should == (0..folder.documents.count)
|
516
520
|
end
|
@@ -526,37 +530,36 @@ describe Positionable do
|
|
526
530
|
let(:start) { 1 }
|
527
531
|
|
528
532
|
it "starts at the given position" do
|
529
|
-
item =
|
533
|
+
item = create(:starting_at_one_item)
|
530
534
|
item.position.should == start
|
531
535
|
end
|
532
536
|
|
533
537
|
it "increments by one the given start position" do
|
534
|
-
items =
|
535
|
-
item =
|
538
|
+
items = create_list(:starting_at_one_item, 5)
|
539
|
+
item = create(:starting_at_one_item)
|
536
540
|
item.position.should == items.size + start
|
537
541
|
end
|
538
542
|
|
539
543
|
it "caracterizes the first record according the start position" do
|
540
|
-
items =
|
541
|
-
items.first.
|
544
|
+
items = create_list(:starting_at_one_item, 5)
|
545
|
+
items.first.should be_first
|
542
546
|
items.but_first.each do |item|
|
543
|
-
item.
|
547
|
+
item.should_not be_first
|
544
548
|
end
|
545
549
|
end
|
546
550
|
|
547
551
|
it "caracterizes the last record according the start position" do
|
548
|
-
items =
|
552
|
+
items = create_list(:starting_at_one_item, 5)
|
549
553
|
items.but_last.each do |item|
|
550
|
-
item.
|
554
|
+
item.should_not be_last
|
551
555
|
end
|
552
|
-
items.last.
|
556
|
+
items.last.should be_last
|
553
557
|
end
|
554
558
|
|
555
559
|
describe "moving" do
|
556
560
|
|
557
561
|
it "does not move anything if new position is before start position" do
|
558
|
-
|
559
|
-
item = items.sample
|
562
|
+
item = create_list(:starting_at_one_item, 5).sample
|
560
563
|
lambda {
|
561
564
|
item.move_to start - 1
|
562
565
|
}.should_not change(item, :position)
|
@@ -567,7 +570,7 @@ describe Positionable do
|
|
567
570
|
describe "range" do
|
568
571
|
|
569
572
|
it "staggers range with start position" do
|
570
|
-
items =
|
573
|
+
items = create_list(:starting_at_one_item, 5)
|
571
574
|
items.sample.range.should == (start..(items.count + start - 1))
|
572
575
|
end
|
573
576
|
|
@@ -580,13 +583,13 @@ describe Positionable do
|
|
580
583
|
describe "asc" do
|
581
584
|
|
582
585
|
it "appends at the last position" do
|
583
|
-
items =
|
584
|
-
item =
|
586
|
+
items = create_list(:asc_item, 5)
|
587
|
+
item = create(:asc_item)
|
585
588
|
item.position.should == items.size
|
586
589
|
end
|
587
590
|
|
588
591
|
it "orders items by ascending position" do
|
589
|
-
|
592
|
+
create_list(:asc_item, 5)
|
590
593
|
AscItem.all.each_with_index do |item, index|
|
591
594
|
item.position.should == index
|
592
595
|
end
|
@@ -597,13 +600,13 @@ describe Positionable do
|
|
597
600
|
describe "desc" do
|
598
601
|
|
599
602
|
it "appends at the last position" do
|
600
|
-
items =
|
601
|
-
item =
|
603
|
+
items = create_list(:desc_item, 5)
|
604
|
+
item = create(:desc_item)
|
602
605
|
item.position.should == items.size
|
603
606
|
end
|
604
607
|
|
605
608
|
it "orders items by descending position" do
|
606
|
-
|
609
|
+
create_list(:desc_item, 5)
|
607
610
|
DescItem.all.reverse.should be_contiguous.starting_at(0)
|
608
611
|
end
|
609
612
|
|
@@ -613,13 +616,12 @@ describe Positionable do
|
|
613
616
|
|
614
617
|
context "mixing options" do
|
615
618
|
|
616
|
-
let!(:groups) {
|
619
|
+
let!(:groups) { create_list(:group_with_complex_items, 5) }
|
617
620
|
let(:start) { 1 } # Check configuration in support/models.rb
|
618
621
|
|
619
622
|
it "manages complex items" do
|
620
623
|
# All options are tested here (grouping, descending ordering and start position at 1)
|
621
624
|
groups.each do |group|
|
622
|
-
size = group.complex_items.size
|
623
625
|
group.complex_items.reverse.should be_contiguous.starting_at(start)
|
624
626
|
end
|
625
627
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: positionable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-05-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -107,8 +107,8 @@ dependencies:
|
|
107
107
|
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '3.1'
|
110
|
-
description: This extension provides contiguous positionning capabilities to
|
111
|
-
models.
|
110
|
+
description: This extension provides contiguous positionning capabilities to your
|
111
|
+
ActiveRecord models.
|
112
112
|
email:
|
113
113
|
- philippe.guegan@gmail.com
|
114
114
|
executables: []
|
@@ -150,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
150
150
|
version: '0'
|
151
151
|
requirements: []
|
152
152
|
rubyforge_project: positionable
|
153
|
-
rubygems_version: 1.8.
|
153
|
+
rubygems_version: 1.8.24
|
154
154
|
signing_key:
|
155
155
|
specification_version: 3
|
156
156
|
summary: A gem for positionning your ActiveRecord models.
|
@@ -161,3 +161,4 @@ test_files:
|
|
161
161
|
- spec/support/matchers/contiguity_matcher.rb
|
162
162
|
- spec/support/models.rb
|
163
163
|
- spec/support/schema.rb
|
164
|
+
has_rdoc:
|