acts_as_restful_list 0.3.0 → 0.4.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/History.rdoc +10 -0
- data/README.rdoc +5 -1
- data/VERSION +1 -1
- data/acts_as_restful_list.gemspec +2 -2
- data/lib/acts_as_restful_list.rb +8 -4
- data/spec/acts_as_restful_list_spec.rb +84 -12
- metadata +4 -4
data/History.rdoc
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
=== Version 0.4.0 / 2010-11-15
|
2
|
+
|
3
|
+
* enhancements
|
4
|
+
* Support Rails optimistic locking. Thanks, Matt Smith (two-bit-fool)
|
5
|
+
|
6
|
+
=== Version 0.3.0 / 2010-11-11
|
7
|
+
|
8
|
+
* enhancements
|
9
|
+
* added ability to scope on a non-integer and non-id columns
|
10
|
+
|
1
11
|
=== Version 0.1.0 / 2010-02-17
|
2
12
|
|
3
13
|
* enhancements
|
data/README.rdoc
CHANGED
@@ -5,6 +5,10 @@ non-standard method calls like insert_at, acts_as_restful_list makes managing li
|
|
5
5
|
simple. You update the position attribute just like you would update anything else
|
6
6
|
and the rest is taken care of for you.
|
7
7
|
|
8
|
+
== Features
|
9
|
+
* Automatically update your list's order through standard REST methods
|
10
|
+
* Support for Rails Optimistic Locking
|
11
|
+
|
8
12
|
== Installation
|
9
13
|
#environment.rb
|
10
14
|
config.gem 'acts_as_restful_list'
|
@@ -60,4 +64,4 @@ Report issues at http://github.com/12spokes/acts_as_restful_list/issues
|
|
60
64
|
|
61
65
|
== Copyright
|
62
66
|
|
63
|
-
Copyright (c) 2010 '
|
67
|
+
Copyright (c) 2010 '12 Spokes'. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{acts_as_restful_list}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["'Trey Bean'"]
|
12
|
-
s.date = %q{2010-11-
|
12
|
+
s.date = %q{2010-11-15}
|
13
13
|
s.description = %q{Just like acts_as_list, but allows updating through standard restful methods.}
|
14
14
|
s.email = %q{trey@12spokes.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/acts_as_restful_list.rb
CHANGED
@@ -4,7 +4,7 @@ module ActsAsRestfulList
|
|
4
4
|
base.extend ClassMethods
|
5
5
|
end
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
module ClassMethods
|
9
9
|
# +acts_as_restful_list+ makes the class it is called on automatically behave like an
|
10
10
|
# ordered list. There are a number of options you can set:
|
@@ -35,6 +35,10 @@ module ActsAsRestfulList
|
|
35
35
|
scopes.join(' AND ')
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
define_method 'optimistic_locking_update' do
|
40
|
+
self.class.column_names.include?("lock_version") ? ", lock_version = (lock_version + 1)" : ""
|
41
|
+
end
|
38
42
|
end
|
39
43
|
end
|
40
44
|
|
@@ -47,15 +51,15 @@ module ActsAsRestfulList
|
|
47
51
|
def reset_order_after_update
|
48
52
|
if self.send( "#{position_column}_changed?" )
|
49
53
|
if self.send( "#{position_column}_was" ) > self.send( position_column )
|
50
|
-
self.class.update_all("#{position_column} = (#{position_column} + 1)", [scope_condition, "#{position_column} >= #{self.send( position_column )}", "id != #{id}", "#{position_column} < #{self.send( "#{position_column}_was" )}"].compact.join(' AND '))
|
54
|
+
self.class.update_all("#{position_column} = (#{position_column} + 1) #{optimistic_locking_update}", [scope_condition, "#{position_column} >= #{self.send( position_column )}", "id != #{id}", "#{position_column} < #{self.send( "#{position_column}_was" )}"].compact.join(' AND '))
|
51
55
|
else
|
52
|
-
self.class.update_all("#{position_column} = (#{position_column} - 1)", [scope_condition, "#{position_column} <= #{self.send( position_column )}", "#{position_column} >= #{self.send( "#{position_column}_was" )}", "id != #{id}"].compact.join(' AND '))
|
56
|
+
self.class.update_all("#{position_column} = (#{position_column} - 1) #{optimistic_locking_update}", [scope_condition, "#{position_column} <= #{self.send( position_column )}", "#{position_column} >= #{self.send( "#{position_column}_was" )}", "id != #{id}"].compact.join(' AND '))
|
53
57
|
end
|
54
58
|
end
|
55
59
|
end
|
56
60
|
|
57
61
|
def reset_order_after_destroy
|
58
|
-
self.class.update_all("#{position_column} = (#{position_column} - 1)", [scope_condition, "#{position_column} > #{self.send( position_column )}"].compact.join(' AND '))
|
62
|
+
self.class.update_all("#{position_column} = (#{position_column} - 1) #{optimistic_locking_update}", [scope_condition, "#{position_column} > #{self.send( position_column )}"].compact.join(' AND '))
|
59
63
|
end
|
60
64
|
end
|
61
65
|
end
|
@@ -12,7 +12,7 @@ describe "ActsAsRestfulList" do
|
|
12
12
|
create_table :mixins do |t|
|
13
13
|
t.column :position, :integer
|
14
14
|
t.column :parent_id, :integer
|
15
|
-
t.column :created_at, :datetime
|
15
|
+
t.column :created_at, :datetime
|
16
16
|
t.column :updated_at, :datetime
|
17
17
|
end
|
18
18
|
end
|
@@ -24,7 +24,7 @@ describe "ActsAsRestfulList" do
|
|
24
24
|
|
25
25
|
after(:all) do
|
26
26
|
Object.send(:remove_const, :Mixin)
|
27
|
-
|
27
|
+
|
28
28
|
ActiveRecord::Base.connection.tables.each do |table|
|
29
29
|
ActiveRecord::Base.connection.drop_table(table)
|
30
30
|
end
|
@@ -85,7 +85,7 @@ describe "ActsAsRestfulList" do
|
|
85
85
|
Mixin.all(:order => 'position ASC').collect(&:position).should == [1,2,3,4]
|
86
86
|
end
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
describe 'reordering on deletion' do
|
90
90
|
it 'should reset the order after deleting a record' do
|
91
91
|
mixin = Mixin.create
|
@@ -106,6 +106,78 @@ describe "ActsAsRestfulList" do
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
109
|
+
describe 'optimistic locking' do
|
110
|
+
before(:all) do
|
111
|
+
ActiveRecord::Schema.define(:version => 1) do
|
112
|
+
create_table :mixins do |t|
|
113
|
+
t.column :position, :integer
|
114
|
+
t.column :parent_id, :integer
|
115
|
+
t.column :lock_version, :integer, :default => 0
|
116
|
+
t.column :created_at, :datetime
|
117
|
+
t.column :updated_at, :datetime
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
class Mixin < ActiveRecord::Base
|
122
|
+
acts_as_restful_list
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
after(:all) do
|
127
|
+
Object.send(:remove_const, :Mixin)
|
128
|
+
|
129
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
130
|
+
ActiveRecord::Base.connection.drop_table(table)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
before(:each) do
|
135
|
+
(1..4).each{ Mixin.create! }
|
136
|
+
end
|
137
|
+
|
138
|
+
describe 'reordering on destroy' do
|
139
|
+
it 'should raise an error for stale objects' do
|
140
|
+
second_mixin = Mixin.first( :conditions => { :position => 2 } )
|
141
|
+
third_mixin = Mixin.first( :conditions => { :position => 3 } )
|
142
|
+
second_mixin.destroy
|
143
|
+
lambda {
|
144
|
+
third_mixin.destroy
|
145
|
+
}.should raise_error(ActiveRecord::StaleObjectError)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should NOT raise an error if update did not affect existing position' do
|
149
|
+
second_mixin = Mixin.first( :conditions => { :position => 2 } )
|
150
|
+
third_mixin = Mixin.first( :conditions => { :position => 3 } )
|
151
|
+
third_mixin.destroy
|
152
|
+
lambda {
|
153
|
+
second_mixin.destroy
|
154
|
+
}.should_not raise_error(ActiveRecord::StaleObjectError)
|
155
|
+
Mixin.all(:order => 'position ASC').collect(&:position).should == [1,2]
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe 'reordering on update' do
|
160
|
+
it 'should raise an error for stale objects' do
|
161
|
+
first_mixin = Mixin.first( :conditions => { :position => 1 } )
|
162
|
+
fourth_mixin = Mixin.first( :conditions => { :position => 4 } )
|
163
|
+
fourth_mixin.update_attributes(:position => 1)
|
164
|
+
lambda {
|
165
|
+
first_mixin.update_attributes(:position => 2)
|
166
|
+
}.should raise_error(ActiveRecord::StaleObjectError)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'should NOT raise an error if update did not affect existing position' do
|
170
|
+
first_mixin = Mixin.first( :conditions => { :position => 1 } )
|
171
|
+
fourth_mixin = Mixin.first( :conditions => { :position => 4 } )
|
172
|
+
fourth_mixin.update_attributes(:position => 2)
|
173
|
+
lambda {
|
174
|
+
first_mixin.update_attributes(:position => 3)
|
175
|
+
}.should_not raise_error(ActiveRecord::StaleObjectError)
|
176
|
+
Mixin.all(:order => 'position ASC').collect(&:position).should == [1,2,3,4]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
109
181
|
|
110
182
|
describe 'declaring acts_as_restful_list and setting the column' do
|
111
183
|
before(:all) do
|
@@ -113,7 +185,7 @@ describe "ActsAsRestfulList" do
|
|
113
185
|
create_table :mixins do |t|
|
114
186
|
t.column :pos, :integer
|
115
187
|
t.column :parent_id, :integer
|
116
|
-
t.column :created_at, :datetime
|
188
|
+
t.column :created_at, :datetime
|
117
189
|
t.column :updated_at, :datetime
|
118
190
|
end
|
119
191
|
end
|
@@ -125,7 +197,7 @@ describe "ActsAsRestfulList" do
|
|
125
197
|
|
126
198
|
after(:all) do
|
127
199
|
Object.send(:remove_const, :Mixin)
|
128
|
-
|
200
|
+
|
129
201
|
ActiveRecord::Base.connection.tables.each do |table|
|
130
202
|
ActiveRecord::Base.connection.drop_table(table)
|
131
203
|
end
|
@@ -178,7 +250,7 @@ describe "ActsAsRestfulList" do
|
|
178
250
|
Mixin.all(:order => 'pos ASC').collect(&:pos).should == [1,2,3,4]
|
179
251
|
end
|
180
252
|
end
|
181
|
-
|
253
|
+
|
182
254
|
describe 'reordering on deletion' do
|
183
255
|
it 'should reset the order after deleting a record' do
|
184
256
|
mixin = Mixin.create
|
@@ -201,7 +273,7 @@ describe "ActsAsRestfulList" do
|
|
201
273
|
create_table :mixins do |t|
|
202
274
|
t.column :position, :integer
|
203
275
|
t.column :parent_id, :integer
|
204
|
-
t.column :created_at, :datetime
|
276
|
+
t.column :created_at, :datetime
|
205
277
|
t.column :updated_at, :datetime
|
206
278
|
end
|
207
279
|
end
|
@@ -213,7 +285,7 @@ describe "ActsAsRestfulList" do
|
|
213
285
|
|
214
286
|
after(:all) do
|
215
287
|
Object.send(:remove_const, :Mixin)
|
216
|
-
|
288
|
+
|
217
289
|
ActiveRecord::Base.connection.tables.each do |table|
|
218
290
|
ActiveRecord::Base.connection.drop_table(table)
|
219
291
|
end
|
@@ -279,7 +351,7 @@ describe "ActsAsRestfulList" do
|
|
279
351
|
create_table :mixins do |t|
|
280
352
|
t.column :position, :integer
|
281
353
|
t.column :parent_id, :integer
|
282
|
-
t.column :created_at, :datetime
|
354
|
+
t.column :created_at, :datetime
|
283
355
|
t.column :updated_at, :datetime
|
284
356
|
end
|
285
357
|
end
|
@@ -291,7 +363,7 @@ describe "ActsAsRestfulList" do
|
|
291
363
|
|
292
364
|
after(:all) do
|
293
365
|
Object.send(:remove_const, :Mixin)
|
294
|
-
|
366
|
+
|
295
367
|
ActiveRecord::Base.connection.tables.each do |table|
|
296
368
|
ActiveRecord::Base.connection.drop_table(table)
|
297
369
|
end
|
@@ -313,7 +385,7 @@ describe "ActsAsRestfulList" do
|
|
313
385
|
create_table :mixins do |t|
|
314
386
|
t.column :position, :integer
|
315
387
|
t.column :parent_name, :string
|
316
|
-
t.column :created_at, :datetime
|
388
|
+
t.column :created_at, :datetime
|
317
389
|
t.column :updated_at, :datetime
|
318
390
|
end
|
319
391
|
end
|
@@ -348,7 +420,7 @@ describe "ActsAsRestfulList" do
|
|
348
420
|
t.column :position, :integer
|
349
421
|
t.column :user_id, :integer
|
350
422
|
t.column :parent_id, :integer
|
351
|
-
t.column :created_at, :datetime
|
423
|
+
t.column :created_at, :datetime
|
352
424
|
t.column :updated_at, :datetime
|
353
425
|
end
|
354
426
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_restful_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "'Trey Bean'"
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-11-
|
18
|
+
date: 2010-11-15 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|