acts_as_restful_list 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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