acts_as_restful_list 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 'Trey Bean'
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = acts_as_restful_list
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 'Trey Bean'. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "acts_as_restful_list"
8
+ gem.summary = %Q{Restful acts_as_list}
9
+ gem.description = %Q{Just like acts_as_list, but allows updating through standard restful methods.}
10
+ gem.email = "trey@12spokes.com"
11
+ gem.homepage = "http://github.com/treybean/acts_as_restful_list"
12
+ gem.authors = ["'Trey Bean'"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "acts_as_restful_list #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
@@ -0,0 +1,51 @@
1
+ module ActsAsRestfulList
2
+ class << self
3
+ def included base #:nodoc:
4
+ base.extend ClassMethods
5
+ end
6
+ end
7
+
8
+ module ClassMethods
9
+ # +acts_as_restful_list+ makes the class it is called on automatically behave like an
10
+ # ordered list. There are a number of options you can set:
11
+ # * +column+: The column to use as the position column. It's set to position by default.
12
+ def acts_as_restful_list(options = {})
13
+ include InstanceMethods
14
+
15
+ configuration = {:column => :position}.merge(options)
16
+
17
+ before_create :set_position
18
+ after_update :reset_order_after_update
19
+ after_destroy :reset_order_after_destroy
20
+
21
+ define_method 'position_column' do
22
+ configuration[:column].to_s
23
+ end
24
+ end
25
+ end
26
+
27
+ module InstanceMethods
28
+ def set_position
29
+ last_record = self.class.last( :order => "#{position_column} ASC" )
30
+ self.send( "#{position_column}=", ( last_record.nil? ? 1 : last_record.send(position_column) + 1 ) )
31
+ end
32
+
33
+ def reset_order_after_update
34
+ if self.send( "#{position_column}_changed?" )
35
+ if self.send( "#{position_column}_was" ) > self.send( position_column )
36
+ self.class.update_all("#{position_column} = (#{position_column} + 1)", "#{position_column} >= #{self.send( position_column )} AND id != #{id}")
37
+ else
38
+ self.class.update_all("#{position_column} = (#{position_column} - 1)", "#{position_column} <= #{self.send( position_column )} AND #{position_column} >= #{self.send( "#{position_column}_was" )} AND id != #{id}")
39
+ end
40
+ end
41
+ end
42
+
43
+ def reset_order_after_destroy
44
+ self.class.update_all("#{position_column} = (#{position_column} - 1)", "#{position_column} > #{self.send( position_column )}")
45
+ end
46
+ end
47
+ end
48
+
49
+ if Object.const_defined?("ActiveRecord")
50
+ ActiveRecord::Base.send(:include, ActsAsRestfulList)
51
+ end
@@ -0,0 +1,185 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "ActsAsRestfulList" do
4
+ after(:each) do
5
+ ActiveRecord::Base.connection.execute("DELETE FROM mixins")
6
+ ActiveRecord::Base.connection.execute("DELETE FROM sqlite_sequence where name='mixins'")
7
+ end
8
+
9
+ describe 'standard declaration with no options' do
10
+ before(:all) do
11
+ ActiveRecord::Schema.define(:version => 1) do
12
+ create_table :mixins do |t|
13
+ t.column :position, :integer
14
+ t.column :parent_id, :integer
15
+ t.column :created_at, :datetime
16
+ t.column :updated_at, :datetime
17
+ end
18
+ end
19
+
20
+ class Mixin < ActiveRecord::Base
21
+ acts_as_restful_list
22
+ end
23
+ end
24
+
25
+ after(:all) do
26
+ Object.send(:remove_const, :Mixin)
27
+
28
+ ActiveRecord::Base.connection.tables.each do |table|
29
+ ActiveRecord::Base.connection.drop_table(table)
30
+ end
31
+ end
32
+
33
+ it "should return position as it's position column" do
34
+ Mixin.new.position_column.should == 'position'
35
+ end
36
+
37
+ it 'should set the position before creating the record' do
38
+ mixin = Mixin.new
39
+ mixin.should_receive(:set_position).and_return(true)
40
+ mixin.save!
41
+ end
42
+
43
+ it 'should save the first record with position 1' do
44
+ Mixin.create!.position.should == 1
45
+ end
46
+
47
+ it 'should put each new record at the end of the list' do
48
+ (1..4).each do |n|
49
+ Mixin.create!.position.should == n
50
+ end
51
+ end
52
+
53
+ describe 'reordering on update' do
54
+ before(:each) do
55
+ (1..4).each{ Mixin.create! }
56
+ end
57
+
58
+ it 'should reset order after updating a record' do
59
+ mixin = Mixin.create
60
+ mixin.should_receive(:reset_order_after_update).and_return(true)
61
+ mixin.save!
62
+ end
63
+
64
+ it 'should automatically reorder the list if a record is updated with a lower position' do
65
+ fourth_mixin = Mixin.first( :conditions => { :position => 4 } )
66
+ fourth_mixin.position = 2
67
+ fourth_mixin.save!
68
+ fourth_mixin.reload.position.should == 2
69
+ Mixin.all(:order => 'position ASC').collect(&:position).should == [1,2,3,4]
70
+ end
71
+
72
+ it 'should automatically reorder the list if a record is updated with a higher position' do
73
+ second_mixin = Mixin.first( :conditions => { :position => 2 } )
74
+ second_mixin.position = 4
75
+ second_mixin.save!
76
+ second_mixin.reload.position.should == 4
77
+ Mixin.all(:order => 'position ASC').collect(&:position).should == [1,2,3,4]
78
+ end
79
+ end
80
+
81
+ describe 'reordering on deletion' do
82
+ it 'should reset the order after deleting a record' do
83
+ mixin = Mixin.create
84
+ mixin.should_receive(:reset_order_after_destroy).and_return(true)
85
+ mixin.destroy
86
+ end
87
+
88
+ it 'should automatically reorder the list if the record id deleted' do
89
+ (1..4).each{ Mixin.create! }
90
+ second_mixin = Mixin.first( :conditions => { :position => 2 } )
91
+ second_mixin.destroy
92
+ Mixin.all(:order => 'position ASC').collect(&:position).should == [1,2,3]
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ describe 'declaring acts_as_restful_list and setting the column' do
99
+ before(:all) do
100
+ ActiveRecord::Schema.define(:version => 1) do
101
+ create_table :mixins do |t|
102
+ t.column :pos, :integer
103
+ t.column :parent_id, :integer
104
+ t.column :created_at, :datetime
105
+ t.column :updated_at, :datetime
106
+ end
107
+ end
108
+
109
+ class Mixin < ActiveRecord::Base
110
+ acts_as_restful_list :column => :pos
111
+ end
112
+ end
113
+
114
+ after(:all) do
115
+ Object.send(:remove_const, :Mixin)
116
+
117
+ ActiveRecord::Base.connection.tables.each do |table|
118
+ ActiveRecord::Base.connection.drop_table(table)
119
+ end
120
+ end
121
+
122
+ it "should return pos as it's position column" do
123
+ Mixin.new.position_column.should == 'pos'
124
+ end
125
+
126
+ it 'should set the position before creating the record' do
127
+ mixin = Mixin.new
128
+ mixin.should_receive(:set_position).and_return(true)
129
+ mixin.save!
130
+ end
131
+
132
+ it 'should save the first record with position 1' do
133
+ Mixin.create!.pos.should == 1
134
+ end
135
+
136
+ it 'should put each new record at the end of the list' do
137
+ (1..4).each do |n|
138
+ Mixin.create!.pos.should == n
139
+ end
140
+ end
141
+
142
+ describe 'reordering on update' do
143
+ before(:each) do
144
+ (1..4).each{ Mixin.create! }
145
+ end
146
+
147
+ it 'should reset order after updating a record' do
148
+ mixin = Mixin.create
149
+ mixin.should_receive(:reset_order_after_update).and_return(true)
150
+ mixin.save!
151
+ end
152
+
153
+ it 'should automatically reorder the list if a record is updated with a lower position' do
154
+ fourth_mixin = Mixin.first( :conditions => { :pos => 4 } )
155
+ fourth_mixin.pos = 2
156
+ fourth_mixin.save!
157
+ fourth_mixin.reload.pos.should == 2
158
+ Mixin.all(:order => 'pos ASC').collect(&:pos).should == [1,2,3,4]
159
+ end
160
+
161
+ it 'should automatically reorder the list if a record is updated with a higher position' do
162
+ second_mixin = Mixin.first( :conditions => { :pos => 2 } )
163
+ second_mixin.pos = 4
164
+ second_mixin.save!
165
+ second_mixin.reload.pos.should == 4
166
+ Mixin.all(:order => 'pos ASC').collect(&:pos).should == [1,2,3,4]
167
+ end
168
+ end
169
+
170
+ describe 'reordering on deletion' do
171
+ it 'should reset the order after deleting a record' do
172
+ mixin = Mixin.create
173
+ mixin.should_receive(:reset_order_after_destroy).and_return(true)
174
+ mixin.destroy
175
+ end
176
+
177
+ it 'should automatically reorder the list if the record id deleted' do
178
+ (1..4).each{ Mixin.create! }
179
+ second_mixin = Mixin.first( :conditions => { :pos => 2 } )
180
+ second_mixin.destroy
181
+ Mixin.all(:order => 'pos ASC').collect(&:pos).should == [1,2,3]
182
+ end
183
+ end
184
+ end
185
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,14 @@
1
+ require 'rubygems'
2
+ gem 'activerecord', '>= 1.15.4.7794'
3
+ require 'active_record'
4
+
5
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
6
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
7
+ require 'acts_as_restful_list'
8
+ require 'spec'
9
+ require 'spec/autorun'
10
+
11
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
12
+
13
+ Spec::Runner.configure do |config|
14
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acts_as_restful_list
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - "'Trey Bean'"
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-14 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ type: :development
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.9
24
+ version:
25
+ description: Just like acts_as_list, but allows updating through standard restful methods.
26
+ email: trey@12spokes.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - lib/acts_as_restful_list.rb
42
+ - spec/acts_as_restful_list_spec.rb
43
+ - spec/spec.opts
44
+ - spec/spec_helper.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/treybean/acts_as_restful_list
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Restful acts_as_list
73
+ test_files:
74
+ - spec/acts_as_restful_list_spec.rb
75
+ - spec/spec_helper.rb