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 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 'Trey Bean'. See LICENSE for details.
67
+ Copyright (c) 2010 '12 Spokes'. See LICENSE for details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.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.3.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-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 = [
@@ -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: 19
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.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-11 00:00:00 -07:00
18
+ date: 2010-11-15 00:00:00 -07:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency