positionable 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/lib/positionable.rb +13 -13
- data/lib/positionable/version.rb +1 -1
- data/positionable.gemspec +1 -0
- data/spec/factories.rb +4 -0
- data/spec/lib/positionable_spec.rb +21 -7
- data/spec/spec_helper.rb +7 -0
- data/spec/support/models.rb +4 -0
- data/spec/support/schema.rb +11 -5
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b8f6aadcd04a2af3bd0c273694b1645d9ddfef2c
|
4
|
+
data.tar.gz: 8e1f5f8db76a76410ebd7566953457b832ffd909
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c1e2f772054b7569e856a0cd242061285e4b5e3101ca790d4688ee507a597287a4c77a57b268f1a772d2f58004d1847665a78208129034ff722a62ed9a17c180
|
7
|
+
data.tar.gz: f02091c09cb80bc3157c34150fd93b13e619e4f42346a859255f404f8041cb26e11f7e9577a407744cbcc87755ccb5f5a8e7987ce826f7aac05529d504cb0395
|
data/.travis.yml
CHANGED
data/lib/positionable.rb
CHANGED
@@ -9,7 +9,7 @@ require 'active_record'
|
|
9
9
|
# to be <em>contiguous</em>, ie.: there is no 'hole' between two adjacent positions.
|
10
10
|
#
|
11
11
|
# Positionable has a strong management of records that belong to a group (a.k.a. scope). When a
|
12
|
-
# record is moved whithin its scope, or from a scope to another, other impacted records are
|
12
|
+
# record is moved whithin its scope, or from a scope to another, other impacted records are
|
13
13
|
# also reordered accordingly.
|
14
14
|
#
|
15
15
|
# You can use the provided instance methods (<tt>up!</tt>, <tt>down!</tt> or <tt>move_to</tt>)
|
@@ -29,12 +29,12 @@ module Positionable
|
|
29
29
|
module PositionableMethods
|
30
30
|
|
31
31
|
# Makes this model positionable.
|
32
|
-
#
|
32
|
+
#
|
33
33
|
# class Item < ActiveRecord::Base
|
34
34
|
# is_positionable
|
35
35
|
# end
|
36
36
|
#
|
37
|
-
# Maybe your items are grouped (typically with a +belongs_to+ association). In this case,
|
37
|
+
# Maybe your items are grouped (typically with a +belongs_to+ association). In this case,
|
38
38
|
# you'll want to restrict the position in each group by declaring the +:scope+ option:
|
39
39
|
#
|
40
40
|
# class Folder < ActiveRecord::Base
|
@@ -48,7 +48,7 @@ module Positionable
|
|
48
48
|
#
|
49
49
|
# By default, position starts by zero. But you may want to change this at the model level,
|
50
50
|
# for instance by starting at one (which seems more natural for some people):
|
51
|
-
#
|
51
|
+
#
|
52
52
|
# class Item < ActiveRecord::Base
|
53
53
|
# is_positionable :start => 1
|
54
54
|
# end
|
@@ -69,7 +69,7 @@ module Positionable
|
|
69
69
|
default_scope { order("#{ActiveRecord::Base.connection.quote_table_name self.table_name}.#{ActiveRecord::Base.connection.quote_column_name 'position'} #{order}") }
|
70
70
|
|
71
71
|
before_create :add_to_bottom
|
72
|
-
before_update :update_position
|
72
|
+
before_update :update_position unless options[:skip] == :update
|
73
73
|
after_destroy :decrement_all_next
|
74
74
|
|
75
75
|
if scope_id_attr
|
@@ -89,9 +89,9 @@ module Positionable
|
|
89
89
|
target_scope_id = scope.nil? ? scope_id : scope.id
|
90
90
|
# Number of records whithin the target scope
|
91
91
|
count = if target_scope_id.nil?
|
92
|
-
self.class.where("#{scope_id_attr} IS NULL").count
|
92
|
+
self.class.base_class.where("#{scope_id_attr} IS NULL").count
|
93
93
|
else
|
94
|
-
self.class.where("#{scope_id_attr} = ?", target_scope_id).count
|
94
|
+
self.class.base_class.where("#{scope_id_attr} = ?", target_scope_id).count
|
95
95
|
end
|
96
96
|
# An additional position is available if this record is new, or if it's moved to another scope
|
97
97
|
if new_record? or target_scope_id != scope_id
|
@@ -212,13 +212,13 @@ module Positionable
|
|
212
212
|
# are ordered by their respective positions, depending on the <tt>order</tt> option
|
213
213
|
# provided to <tt>is_positionable</tt>.
|
214
214
|
def all_next
|
215
|
-
self.class.where("#{scoped_position} > ?", position)
|
215
|
+
self.class.base_class.where("#{scoped_position} > ?", position)
|
216
216
|
end
|
217
217
|
|
218
|
-
# All the next records <em>of the old scope</em>, whose positions are greater
|
218
|
+
# All the next records <em>of the old scope</em>, whose positions are greater
|
219
219
|
# than this record before it was moved from its old record.
|
220
220
|
def all_next_was
|
221
|
-
self.class.where("#{scoped_position_was} > ?", position_was)
|
221
|
+
self.class.base_class.where("#{scoped_position_was} > ?", position_was)
|
222
222
|
end
|
223
223
|
|
224
224
|
# Gives the next sibling record, whose position is right before this record.
|
@@ -230,7 +230,7 @@ module Positionable
|
|
230
230
|
# are ordered by their respective positions, depending on the <tt>order</tt> option
|
231
231
|
# provided to <tt>is_positionable</tt> (ascending by default).
|
232
232
|
def all_previous
|
233
|
-
self.class.where("#{scoped_position} < ?", position)
|
233
|
+
self.class.base_class.where("#{scoped_position} < ?", position)
|
234
234
|
end
|
235
235
|
|
236
236
|
private
|
@@ -242,12 +242,12 @@ module Positionable
|
|
242
242
|
|
243
243
|
# Finds the record at the given position.
|
244
244
|
def at(position)
|
245
|
-
self.class.where("#{scoped_position} = ?", position).limit(1).first
|
245
|
+
self.class.base_class.where("#{scoped_position} = ?", position).limit(1).first
|
246
246
|
end
|
247
247
|
|
248
248
|
# Swaps this record's position with the other provided record.
|
249
249
|
def swap_with(other)
|
250
|
-
self.class.transaction do
|
250
|
+
self.class.base_class.transaction do
|
251
251
|
old_position = position
|
252
252
|
update_attribute(:position, other.position)
|
253
253
|
other.update_attribute(:position, old_position)
|
data/lib/positionable/version.rb
CHANGED
data/positionable.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_development_dependency "sqlite3"
|
24
24
|
s.add_development_dependency "simplecov"
|
25
25
|
s.add_development_dependency "factory_girl"
|
26
|
+
s.add_development_dependency "byebug"
|
26
27
|
|
27
28
|
s.add_runtime_dependency "activerecord", ">= 3.1"
|
28
29
|
end
|
data/spec/factories.rb
CHANGED
@@ -171,7 +171,7 @@ describe Positionable do
|
|
171
171
|
describe "moving" do
|
172
172
|
|
173
173
|
context "mass-assignement" do
|
174
|
-
|
174
|
+
|
175
175
|
it "reorders records when position is updated" do
|
176
176
|
old_position = middle.position
|
177
177
|
new_position = old_position + 3
|
@@ -197,7 +197,7 @@ describe Positionable do
|
|
197
197
|
middle.update_attributes({ :position => -1 })
|
198
198
|
items.should be_contiguous.starting_at(0)
|
199
199
|
end
|
200
|
-
|
200
|
+
|
201
201
|
end
|
202
202
|
|
203
203
|
it "also moves the previous records when moving to a lower position" do
|
@@ -407,7 +407,7 @@ describe Positionable do
|
|
407
407
|
previous.reload.position.should == position
|
408
408
|
middle.position.should == position - 1
|
409
409
|
neXt.reload.position.should == position + 1
|
410
|
-
end
|
410
|
+
end
|
411
411
|
end
|
412
412
|
|
413
413
|
it "reorders the records positions after downing" do
|
@@ -446,24 +446,24 @@ describe Positionable do
|
|
446
446
|
let!(:new_documents) { create_list(:document, old_folder.documents.count + 1, :folder => new_folder) }
|
447
447
|
|
448
448
|
it "moves to bottom position when scope has changed but position is out of range" do
|
449
|
-
document.update_attributes( {:
|
449
|
+
document.update_attributes( {:folder => new_folder, :position => new_documents.count + 10 } )
|
450
450
|
document.position.should == new_folder.documents.count - 1
|
451
451
|
document.should be_last
|
452
452
|
end
|
453
453
|
|
454
454
|
it "keeps position when scope has changed but position belongs to range" do
|
455
455
|
lambda {
|
456
|
-
document.update_attributes( {:
|
456
|
+
document.update_attributes( {:folder => new_folder} )
|
457
457
|
}.should_not change(document, :position)
|
458
458
|
end
|
459
459
|
|
460
460
|
it "reorders records of target scope" do
|
461
|
-
document.update_attributes( {:
|
461
|
+
document.update_attributes( {:folder => new_folder} )
|
462
462
|
new_folder.reload.documents.should be_contiguous.starting_at(0)
|
463
463
|
end
|
464
464
|
|
465
465
|
it "reorders records of previous scope" do
|
466
|
-
document.update_attributes( {:
|
466
|
+
document.update_attributes( {:folder => new_folder} )
|
467
467
|
old_folder.reload.documents.should be_contiguous.starting_at(0)
|
468
468
|
end
|
469
469
|
|
@@ -632,4 +632,18 @@ describe Positionable do
|
|
632
632
|
|
633
633
|
end
|
634
634
|
|
635
|
+
context "skip update" do
|
636
|
+
|
637
|
+
let(:items) { create_list(:skip_update_item, 5) }
|
638
|
+
let(:item) { items[2] }
|
639
|
+
|
640
|
+
it "does not update sibbling positions" do
|
641
|
+
item.position.should == 2 # Meta!
|
642
|
+
item.update(position: 1)
|
643
|
+
item.position.should == 1 # Meta!
|
644
|
+
SkipUpdateItem.all.map(&:position).should == [0, 1, 1, 3, 4]
|
645
|
+
end
|
646
|
+
|
647
|
+
end
|
648
|
+
|
635
649
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,8 @@ SimpleCov.start do
|
|
3
3
|
add_filter "/spec/support/"
|
4
4
|
end
|
5
5
|
|
6
|
+
require 'byebug'
|
7
|
+
|
6
8
|
require 'factory_girl'
|
7
9
|
FactoryGirl.find_definitions
|
8
10
|
include FactoryGirl::Syntax::Methods
|
@@ -15,6 +17,11 @@ load File.dirname(__FILE__) + '/support/schema.rb'
|
|
15
17
|
load File.dirname(__FILE__) + '/support/models.rb'
|
16
18
|
load File.dirname(__FILE__) + '/support/matchers/contiguity_matcher.rb'
|
17
19
|
|
20
|
+
RSpec.configure do |config|
|
21
|
+
config.filter_run focus: true
|
22
|
+
config.run_all_when_everything_filtered = true
|
23
|
+
end
|
24
|
+
|
18
25
|
class Array
|
19
26
|
|
20
27
|
def but_last
|
data/spec/support/models.rb
CHANGED
data/spec/support/schema.rb
CHANGED
@@ -3,19 +3,19 @@ ActiveRecord::Schema.define do
|
|
3
3
|
|
4
4
|
create_table :folders, :force => true do |t|
|
5
5
|
t.string :title
|
6
|
-
t.timestamps
|
6
|
+
t.timestamps null: true
|
7
7
|
end
|
8
8
|
|
9
9
|
create_table :documents, :force => true do |t|
|
10
10
|
t.integer :folder_id
|
11
11
|
t.string :title
|
12
12
|
t.integer :position
|
13
|
-
t.timestamps
|
13
|
+
t.timestamps null: true
|
14
14
|
end
|
15
15
|
|
16
16
|
create_table :groups, :force => true do |t|
|
17
17
|
t.string :title
|
18
|
-
t.timestamps
|
18
|
+
t.timestamps null: true
|
19
19
|
end
|
20
20
|
|
21
21
|
create_table :items, :force => true do |t|
|
@@ -23,11 +23,17 @@ ActiveRecord::Schema.define do
|
|
23
23
|
t.string :title
|
24
24
|
t.integer :position
|
25
25
|
t.string :type
|
26
|
-
t.timestamps
|
26
|
+
t.timestamps null: true
|
27
27
|
end
|
28
28
|
|
29
29
|
create_table :dummies, :force => true do |t|
|
30
30
|
t.string :title
|
31
|
-
t.timestamps
|
31
|
+
t.timestamps null: true
|
32
|
+
end
|
33
|
+
|
34
|
+
create_table :skip_update_items, :force => true do |t|
|
35
|
+
t.string :title
|
36
|
+
t.integer :position
|
37
|
+
t.timestamps null: true
|
32
38
|
end
|
33
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: positionable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Philippe Guégan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-06-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: byebug
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: activerecord
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
150
|
version: '0'
|
137
151
|
requirements: []
|
138
152
|
rubyforge_project: positionable
|
139
|
-
rubygems_version: 2.
|
153
|
+
rubygems_version: 2.4.6
|
140
154
|
signing_key:
|
141
155
|
specification_version: 4
|
142
156
|
summary: A gem for positionning your ActiveRecord models.
|