acts_as_orderable 0.1.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.tar.gz.sig +0 -0
- data/CHANGELOG.rdoc +2 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +20 -0
- data/Manifest +10 -0
- data/README.md +84 -0
- data/Rakefile +13 -0
- data/acts_as_orderable.gemspec +37 -0
- data/init.rb +2 -0
- data/lib/acts_as_orderable.rb +127 -0
- data/spec/acts_as_orderable_spec.rb +315 -0
- data/spec/spec_helper.rb +29 -0
- metadata +115 -0
- metadata.gz.sig +2 -0
data.tar.gz.sig
ADDED
Binary file
|
data/CHANGELOG.rdoc
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Maciej Mensfeld
|
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/Manifest
ADDED
data/README.md
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
# ActsAsOrderable
|
2
|
+
## Install
|
3
|
+
|
4
|
+
gem install acts_as_orderable
|
5
|
+
|
6
|
+
and in your Gemfile:
|
7
|
+
|
8
|
+
gem 'acts_as_orderable'
|
9
|
+
|
10
|
+
Model declaration:
|
11
|
+
|
12
|
+
class CoolClass < ActiveRecord::Base
|
13
|
+
acts_as_orderable
|
14
|
+
end
|
15
|
+
|
16
|
+
## About
|
17
|
+
|
18
|
+
Simple Rails gem allowing ActiveRecord models to have order and to move them up and down
|
19
|
+
|
20
|
+
Requirements
|
21
|
+
|
22
|
+
table.integer :element_order, :default => 0, :null => false
|
23
|
+
|
24
|
+
It works well with acts_ac_tree (each node has its own order so they don't interfere with each other)
|
25
|
+
|
26
|
+
Use `:position => :first` or `:position => :last` to set default new element behavior - should it be append as and first or last element. Default is `:last`. This default behavior will also be used when switching parents when you use `acts_as_tree`.
|
27
|
+
|
28
|
+
## Example
|
29
|
+
|
30
|
+
class CoolClass < ActiveRecord::Base
|
31
|
+
acts_as_orderable
|
32
|
+
end
|
33
|
+
|
34
|
+
# Creating some records record
|
35
|
+
a = CoolClass.new(:name => A); a.save
|
36
|
+
b = CoolClass.new(:name => B); b.save
|
37
|
+
c = CoolClass.new(:name => C); c.save
|
38
|
+
d = CoolClass.new(:name => D); d.save
|
39
|
+
|
40
|
+
#Order:
|
41
|
+
0 => A
|
42
|
+
1 => B
|
43
|
+
2 => C
|
44
|
+
3 => D
|
45
|
+
|
46
|
+
Lets take element C and lest move it 1 element up
|
47
|
+
|
48
|
+
c.move_up(1)
|
49
|
+
|
50
|
+
#New Order:
|
51
|
+
0 => A
|
52
|
+
1 => C
|
53
|
+
2 => B
|
54
|
+
3 => D
|
55
|
+
|
56
|
+
Now lest move C 2 elements down
|
57
|
+
|
58
|
+
c.move_down(2)
|
59
|
+
|
60
|
+
# Order:
|
61
|
+
0 => A
|
62
|
+
1 => B
|
63
|
+
2 => D
|
64
|
+
3 => C
|
65
|
+
|
66
|
+
# Additional notes
|
67
|
+
|
68
|
+
With acts_as_tree plugin, you use it in the same way, just remember that you operate on a node order.
|
69
|
+
|
70
|
+
There is one more thing: if you look into element_order column, numbers are not always like: 0, 1, 2, 3, 4, etc. They are more like 0, 1, 23, 452, 523.
|
71
|
+
That's because when you delete a row, there will be deleted also one "order". But don't worry, everything works fine even then.
|
72
|
+
|
73
|
+
## Note on Patches/Pull Requests
|
74
|
+
|
75
|
+
* Fork the project.
|
76
|
+
* Make your feature addition or bug fix.
|
77
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
78
|
+
* Commit, do not mess with Rakefile, version, or history.
|
79
|
+
(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)
|
80
|
+
* Send me a pull request. Bonus points for topic branches.
|
81
|
+
|
82
|
+
## Copyright
|
83
|
+
|
84
|
+
Copyright (c) 2011 Maciej Mensfeld. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('acts_as_orderable', '0.1.0') do |p|
|
6
|
+
p.description = "Rails gem allowing ActiveRecord models to have order and to move them up and down"
|
7
|
+
p.url = "https://github.com/mensfeld/Acts-as-Orderable"
|
8
|
+
p.author = "Maciej Mensfeld"
|
9
|
+
p.email = "maciej@mensfeld.pl"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.development_dependencies = ["rspec >=2.0.0", "active_record"]
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{acts_as_orderable}
|
5
|
+
s.version = "0.1.0"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Maciej Mensfeld"]
|
9
|
+
s.cert_chain = ["/home/mencio/.cert_keys/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2011-04-17}
|
11
|
+
s.description = %q{Rails gem allowing ActiveRecord models to have order and to move them up and down}
|
12
|
+
s.email = %q{maciej@mensfeld.pl}
|
13
|
+
s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.md", "lib/acts_as_orderable.rb"]
|
14
|
+
s.files = ["CHANGELOG.rdoc", "Gemfile", "MIT-LICENSE", "Manifest", "README.md", "Rakefile", "init.rb", "lib/acts_as_orderable.rb", "spec/acts_as_orderable_spec.rb", "spec/spec_helper.rb", "acts_as_orderable.gemspec"]
|
15
|
+
s.homepage = %q{https://github.com/mensfeld/Acts-as-Orderable}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Acts_as_orderable", "--main", "README.md"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{acts_as_orderable}
|
19
|
+
s.rubygems_version = %q{1.5.2}
|
20
|
+
s.signing_key = %q{/home/mencio/.cert_keys/gem-private_key.pem}
|
21
|
+
s.summary = %q{Rails gem allowing ActiveRecord models to have order and to move them up and down}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
28
|
+
s.add_development_dependency(%q<active_record>, [">= 0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
31
|
+
s.add_dependency(%q<active_record>, [">= 0"])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
35
|
+
s.add_dependency(%q<active_record>, [">= 0"])
|
36
|
+
end
|
37
|
+
end
|
data/init.rb
ADDED
@@ -0,0 +1,127 @@
|
|
1
|
+
module Acts
|
2
|
+
module AsOrderable
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.extend AddActsAsMethod
|
6
|
+
end
|
7
|
+
|
8
|
+
module AddActsAsMethod
|
9
|
+
|
10
|
+
# Should new element be first || last
|
11
|
+
def acts_as_orderable(*sources)
|
12
|
+
class_eval <<-END
|
13
|
+
scope :ordered, order('element_order ASC')
|
14
|
+
after_create :init_me!
|
15
|
+
include Acts::AsOrderable::InstanceMethods
|
16
|
+
END
|
17
|
+
|
18
|
+
options = sources.extract_options!.stringify_keys
|
19
|
+
new_pos = options.delete("position")
|
20
|
+
new_pos = (new_pos && new_pos.to_sym == :first) ? :first : :last
|
21
|
+
|
22
|
+
parent_column = options.delete("tree_column")
|
23
|
+
# Determine tree column (first from param - else check default acts_as_tree "parent_id")
|
24
|
+
unless parent_column
|
25
|
+
parent_column = 'parent_id' if self.column_names.include? 'parent_id'
|
26
|
+
end
|
27
|
+
|
28
|
+
# Set class attributes
|
29
|
+
cattr_accessor :new_element_position
|
30
|
+
self.new_element_position = new_pos
|
31
|
+
cattr_accessor :parent_column
|
32
|
+
self.parent_column = parent_column
|
33
|
+
|
34
|
+
# Define methods for assigning new parent - when we change parent
|
35
|
+
# we need to be first or last element (according to new_el_pos)
|
36
|
+
self.send(:define_method, "#{parent_column}=".to_sym) do |new_parent|
|
37
|
+
super new_parent
|
38
|
+
# If object exist (been saved and we're just changing its parent)
|
39
|
+
init_me! unless self.new_record?
|
40
|
+
end if parent_column
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Istance methods
|
45
|
+
module InstanceMethods
|
46
|
+
|
47
|
+
# Fetches previous element - if there's no previous elements - return nil
|
48
|
+
def previous
|
49
|
+
self.class.where("element_order < #{self.element_order} #{search_node_query}").order("element_order DESC").limit(1).first
|
50
|
+
end
|
51
|
+
|
52
|
+
# Fetches previous element - if there's no previous elements - return nil
|
53
|
+
def next
|
54
|
+
self.class.where("element_order > #{self.element_order} #{search_node_query}").order("element_order ASC").limit(1).first
|
55
|
+
end
|
56
|
+
|
57
|
+
def move_up(steps = 1)
|
58
|
+
move(steps)
|
59
|
+
end
|
60
|
+
|
61
|
+
def move_down(steps = 1)
|
62
|
+
move(-steps)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
# Set default order
|
68
|
+
def init_me!
|
69
|
+
self.element_order = 0
|
70
|
+
if self.class.new_element_position == :first
|
71
|
+
self.class.where("id != #{self.id} #{search_node_query}").all.each do |el|
|
72
|
+
el.element_order += 1
|
73
|
+
el.save
|
74
|
+
end
|
75
|
+
else
|
76
|
+
el = self.class.where("id != #{self.id} #{search_node_query}").order('element_order DESC').limit(1).first
|
77
|
+
if el
|
78
|
+
self.element_order = el.element_order+1
|
79
|
+
else
|
80
|
+
self.element_order = 0
|
81
|
+
end
|
82
|
+
end
|
83
|
+
self.save
|
84
|
+
end
|
85
|
+
|
86
|
+
# Moves us up (+) or down (-)
|
87
|
+
def move(steps)
|
88
|
+
# If you want to stay in place - just stay
|
89
|
+
return if steps == 0 || self.class.count < 2
|
90
|
+
|
91
|
+
# Lets pick those records which are - we limit query - because we only
|
92
|
+
# need those objects that are on our "way" to a new location
|
93
|
+
way = steps < 0 ? ' > ' : ' < '
|
94
|
+
way_order = steps < 0 ? 'ASC' : 'DESC'
|
95
|
+
els = self.class.where("element_order #{way} ? #{search_node_query}
|
96
|
+
AND id != ?", self.element_order, self.id).order("element_order #{way_order}").limit(steps.abs)
|
97
|
+
|
98
|
+
return unless els.count > 0
|
99
|
+
|
100
|
+
our_new_order = els.first.element_order
|
101
|
+
els.each do |el|
|
102
|
+
el.element_order += steps > 0 ? 1 : -1
|
103
|
+
el.save
|
104
|
+
end
|
105
|
+
self.element_order = our_new_order
|
106
|
+
self.save
|
107
|
+
end
|
108
|
+
|
109
|
+
# Builds query part used to fetch only elements from uor node (or do nothing)
|
110
|
+
def search_node_query(init_end = true)
|
111
|
+
p_c = self.class.parent_column
|
112
|
+
# If parent exists - fetch our parent_id and put it into query
|
113
|
+
if p_c
|
114
|
+
parent_id_query = "#{p_c} "
|
115
|
+
parent_id_query += self.send(p_c) ? "= #{self.send(p_c)}" : 'IS NULL'
|
116
|
+
parent_id_query = "AND #{parent_id_query}" if init_end
|
117
|
+
else
|
118
|
+
parent_id_query = nil
|
119
|
+
end
|
120
|
+
parent_id_query
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
ActiveRecord::Base.send(:include, Acts::AsOrderable)
|
@@ -0,0 +1,315 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
class CoolElement < ActiveRecord::Base
|
6
|
+
acts_as_orderable
|
7
|
+
end
|
8
|
+
|
9
|
+
class CoolerElement < ActiveRecord::Base
|
10
|
+
acts_as_orderable :position => :first
|
11
|
+
end
|
12
|
+
|
13
|
+
class WayCoolerElement < ActiveRecord::Base
|
14
|
+
acts_as_tree
|
15
|
+
acts_as_orderable
|
16
|
+
end
|
17
|
+
|
18
|
+
describe CoolElement do
|
19
|
+
subject { CoolElement }
|
20
|
+
before(:each){ CoolElement.destroy_all}
|
21
|
+
|
22
|
+
context "when adding first element" do
|
23
|
+
it "always should have order equal 0" do
|
24
|
+
a = subject.new
|
25
|
+
a.save
|
26
|
+
a.element_order.should == 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when we add second and third elements" do
|
31
|
+
|
32
|
+
it "should be in a correct order" do
|
33
|
+
a=subject.create; b=subject.create; c=subject.create
|
34
|
+
a.reload; b.reload; c.reload
|
35
|
+
a.element_order.should == 0
|
36
|
+
b.element_order.should == 1
|
37
|
+
c.element_order.should == 2
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return valid previous element" do
|
41
|
+
a=subject.create; b=subject.create; c=subject.create
|
42
|
+
a.reload; b.reload; c.reload
|
43
|
+
a.previous.should == nil
|
44
|
+
b.previous.should == a
|
45
|
+
c.previous.should == b
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should return valid next element" do
|
49
|
+
a=subject.create; b=subject.create; c=subject.create
|
50
|
+
a.reload; b.reload; c.reload
|
51
|
+
a.next.should == b
|
52
|
+
b.next.should == c
|
53
|
+
c.next.should == nil
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should be able to move them up" do
|
57
|
+
a=subject.create; b=subject.create; c=subject.create
|
58
|
+
a.reload; b.reload; c.reload
|
59
|
+
c.move_up
|
60
|
+
a.reload; b.reload; c.reload
|
61
|
+
a.element_order.should == 0
|
62
|
+
c.element_order.should == 1
|
63
|
+
b.element_order.should == 2
|
64
|
+
c.move_up
|
65
|
+
a.reload; b.reload; c.reload
|
66
|
+
c.element_order.should == 0
|
67
|
+
a.element_order.should == 1
|
68
|
+
b.element_order.should == 2
|
69
|
+
c.move_up
|
70
|
+
a.reload; b.reload; c.reload
|
71
|
+
c.element_order.should == 0
|
72
|
+
a.element_order.should == 1
|
73
|
+
b.element_order.should == 2
|
74
|
+
a.move_up
|
75
|
+
a.reload; b.reload; c.reload
|
76
|
+
a.element_order.should == 0
|
77
|
+
c.element_order.should == 1
|
78
|
+
b.element_order.should == 2
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be able to move them down" do
|
82
|
+
a=subject.create; b=subject.create; c=subject.create
|
83
|
+
a.reload; b.reload; c.reload
|
84
|
+
a.move_down
|
85
|
+
a.reload; b.reload; c.reload
|
86
|
+
b.element_order.should == 0
|
87
|
+
a.element_order.should == 1
|
88
|
+
c.element_order.should == 2
|
89
|
+
a.move_down
|
90
|
+
a.reload; b.reload; c.reload
|
91
|
+
b.element_order.should == 0
|
92
|
+
c.element_order.should == 1
|
93
|
+
a.element_order.should == 2
|
94
|
+
a.move_down
|
95
|
+
a.reload; b.reload; c.reload
|
96
|
+
b.element_order.should == 0
|
97
|
+
c.element_order.should == 1
|
98
|
+
a.element_order.should == 2
|
99
|
+
b.move_down
|
100
|
+
a.reload; b.reload; c.reload
|
101
|
+
c.element_order.should == 0
|
102
|
+
b.element_order.should == 1
|
103
|
+
a.element_order.should == 2
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when we delete one" do
|
109
|
+
it "should work just fine" do
|
110
|
+
a=subject.create; b=subject.create; c=subject.create; d=subject.create
|
111
|
+
a.reload; b.reload; c.reload; d.reload
|
112
|
+
b.destroy
|
113
|
+
a.reload; c.reload; d.reload
|
114
|
+
a.move_down
|
115
|
+
a.reload; c.reload; d.reload
|
116
|
+
a.element_order.should be > c.element_order
|
117
|
+
a.element_order.should be < d.element_order
|
118
|
+
a.move_up
|
119
|
+
a.reload; c.reload; d.reload
|
120
|
+
a.element_order.should be < c.element_order
|
121
|
+
a.element_order.should be < d.element_order
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
describe CoolerElement do
|
128
|
+
subject { CoolerElement }
|
129
|
+
before(:each){ CoolerElement.destroy_all}
|
130
|
+
|
131
|
+
context "when adding first element" do
|
132
|
+
it "always should have order equal 0" do
|
133
|
+
a = subject.new
|
134
|
+
a.save
|
135
|
+
a.element_order.should == 0
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
context "when we add second and third elements" do
|
140
|
+
|
141
|
+
it "should be in a correct order" do
|
142
|
+
a=subject.create; b=subject.create; c=subject.create
|
143
|
+
a.reload; b.reload; c.reload
|
144
|
+
c.element_order.should == 0
|
145
|
+
b.element_order.should == 1
|
146
|
+
a.element_order.should == 2
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should return valid previous element" do
|
150
|
+
a=subject.create; b=subject.create; c=subject.create
|
151
|
+
a.reload; b.reload; c.reload
|
152
|
+
c.previous.should == nil
|
153
|
+
b.previous.should == c
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should return valid next element" do
|
157
|
+
a=subject.create; b=subject.create; c=subject.create
|
158
|
+
a.reload; b.reload; c.reload
|
159
|
+
a.next.should == nil
|
160
|
+
b.next.should == a
|
161
|
+
c.next.should == b
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should be able to move them up" do
|
165
|
+
a=subject.create; b=subject.create; c=subject.create
|
166
|
+
a.reload; b.reload; c.reload
|
167
|
+
a.move_up
|
168
|
+
a.reload; b.reload; c.reload
|
169
|
+
c.element_order.should == 0
|
170
|
+
a.element_order.should == 1
|
171
|
+
b.element_order.should == 2
|
172
|
+
a.move_up
|
173
|
+
a.reload; b.reload; c.reload
|
174
|
+
a.element_order.should == 0
|
175
|
+
c.element_order.should == 1
|
176
|
+
b.element_order.should == 2
|
177
|
+
a.move_up
|
178
|
+
a.reload; b.reload; c.reload
|
179
|
+
a.element_order.should == 0
|
180
|
+
c.element_order.should == 1
|
181
|
+
b.element_order.should == 2
|
182
|
+
b.move_up
|
183
|
+
a.reload; b.reload; c.reload
|
184
|
+
a.element_order.should == 0
|
185
|
+
b.element_order.should == 1
|
186
|
+
c.element_order.should == 2
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should be able to move them down" do
|
190
|
+
a=subject.create; b=subject.create; c=subject.create
|
191
|
+
a.reload; b.reload; c.reload
|
192
|
+
c.move_down
|
193
|
+
a.reload; b.reload; c.reload
|
194
|
+
b.element_order.should == 0
|
195
|
+
c.element_order.should == 1
|
196
|
+
a.element_order.should == 2
|
197
|
+
c.move_down
|
198
|
+
a.reload; b.reload; c.reload
|
199
|
+
b.element_order.should == 0
|
200
|
+
a.element_order.should == 1
|
201
|
+
c.element_order.should == 2
|
202
|
+
c.move_down
|
203
|
+
a.reload; b.reload; c.reload
|
204
|
+
b.element_order.should == 0
|
205
|
+
a.element_order.should == 1
|
206
|
+
c.element_order.should == 2
|
207
|
+
b.move_down
|
208
|
+
a.reload; b.reload; c.reload
|
209
|
+
a.element_order.should == 0
|
210
|
+
b.element_order.should == 1
|
211
|
+
c.element_order.should == 2
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
context "when we delete one" do
|
217
|
+
it "should work just fine" do
|
218
|
+
a=subject.create; b=subject.create; c=subject.create; d=subject.create
|
219
|
+
a.reload; b.reload; c.reload; d.reload
|
220
|
+
b.destroy
|
221
|
+
a.reload; c.reload; d.reload
|
222
|
+
d.move_down
|
223
|
+
a.reload; c.reload; d.reload
|
224
|
+
d.element_order.should be > c.element_order
|
225
|
+
d.element_order.should be < a.element_order
|
226
|
+
d.move_up
|
227
|
+
a.reload; c.reload; d.reload
|
228
|
+
d.element_order.should be < c.element_order
|
229
|
+
d.element_order.should be < a.element_order
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
end
|
234
|
+
|
235
|
+
describe WayCoolerElement do
|
236
|
+
subject { WayCoolerElement }
|
237
|
+
before(:each){ WayCoolerElement.destroy_all}
|
238
|
+
|
239
|
+
context "when adding first child element" do
|
240
|
+
|
241
|
+
it "always should have order equal 0" do
|
242
|
+
a = ''
|
243
|
+
5.times {a = subject.create}
|
244
|
+
a = a.children.create
|
245
|
+
a.save
|
246
|
+
a.element_order.should == 0
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
context "when switching roots order" do
|
252
|
+
|
253
|
+
it "should not interfere with children" do
|
254
|
+
a = subject.create
|
255
|
+
b = subject.create
|
256
|
+
a.reload; b.reload
|
257
|
+
a.element_order.should == 0
|
258
|
+
b.element_order.should == 1
|
259
|
+
aa = a.children.create
|
260
|
+
ab = a.children.create
|
261
|
+
ac = a.children.create
|
262
|
+
ba = b.children.create
|
263
|
+
bb = b.children.create
|
264
|
+
bc = b.children.create
|
265
|
+
a.reload; b.reload
|
266
|
+
aa.reload; ab.reload; ac.reload;
|
267
|
+
ba.reload; bb.reload; bc.reload;
|
268
|
+
a.element_order.should == 0
|
269
|
+
b.element_order.should == 1
|
270
|
+
aa.element_order.should == 0
|
271
|
+
ab.element_order.should == 1
|
272
|
+
ac.element_order.should == 2
|
273
|
+
ba.element_order.should == 0
|
274
|
+
bb.element_order.should == 1
|
275
|
+
bc.element_order.should == 2
|
276
|
+
a.move_down
|
277
|
+
a.reload; b.reload
|
278
|
+
a.element_order.should == 1
|
279
|
+
b.element_order.should == 0
|
280
|
+
aa.reload; ab.reload; ac.reload;
|
281
|
+
ba.reload; bb.reload; bc.reload;
|
282
|
+
aa.element_order.should == 0
|
283
|
+
ab.element_order.should == 1
|
284
|
+
ac.element_order.should == 2
|
285
|
+
ba.element_order.should == 0
|
286
|
+
bb.element_order.should == 1
|
287
|
+
bc.element_order.should == 2
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
context "when changing root element" do
|
293
|
+
it "should be last" do
|
294
|
+
a = subject.create
|
295
|
+
b = subject.create
|
296
|
+
aa = a.children.create
|
297
|
+
ab = a.children.create
|
298
|
+
a.reload; b.reload; aa.reload; ab.reload
|
299
|
+
aa.parent_id = nil
|
300
|
+
aa.save
|
301
|
+
a.reload; b.reload; aa.reload; ab.reload
|
302
|
+
a.element_order.should == 0
|
303
|
+
b.element_order.should == 1
|
304
|
+
aa.element_order.should == 2
|
305
|
+
ac = a.children.create
|
306
|
+
a.reload; b.reload; aa.reload; ab.reload; ac.reload
|
307
|
+
a.element_order.should == 0
|
308
|
+
b.element_order.should == 1
|
309
|
+
aa.element_order.should == 2
|
310
|
+
ab.element_order.should == 1
|
311
|
+
ac.element_order.should == 2
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'active_record'
|
7
|
+
require 'acts_as_orderable'
|
8
|
+
require 'acts_as_tree'
|
9
|
+
|
10
|
+
ActiveRecord::Base.establish_connection(
|
11
|
+
:adapter => "sqlite3",
|
12
|
+
:database => ":memory:"
|
13
|
+
)
|
14
|
+
|
15
|
+
ActiveRecord::Schema.define do
|
16
|
+
create_table :cool_elements do |table|
|
17
|
+
table.integer :element_order, :default => 0
|
18
|
+
end
|
19
|
+
|
20
|
+
create_table :cooler_elements do |table|
|
21
|
+
table.integer :element_order, :default => 0
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :way_cooler_elements do |table|
|
25
|
+
table.integer :parent_id
|
26
|
+
table.integer :element_order, :default => 0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_orderable
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Maciej Mensfeld
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MQ8wDQYDVQQDDAZtYWNp
|
15
|
+
ZWoxGDAWBgoJkiaJk/IsZAEZFghtZW5zZmVsZDESMBAGCgmSJomT8ixkARkWAnBs
|
16
|
+
MB4XDTExMDQwOTA5NDcyMloXDTEyMDQwODA5NDcyMlowPzEPMA0GA1UEAwwGbWFj
|
17
|
+
aWVqMRgwFgYKCZImiZPyLGQBGRYIbWVuc2ZlbGQxEjAQBgoJkiaJk/IsZAEZFgJw
|
18
|
+
bDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL0+nG3V4/exIeiJ0IN+
|
19
|
+
wVfq8Utcu4Qpo+58EIVMIu3FiK+8w6MBvatZnUrRu12pqWLw9xrUkCiYeRErD+jF
|
20
|
+
AmdggIM/tu9CcjvURXH7VeTzOVA+pnV+eJWMD61o8HljFVcb/nyEYYVKErtr9/O4
|
21
|
+
QrIGv5lnszq1PMj2sBMy2gOP1YnzawncMLmkpp/T5SU4JZ5gAktGMRVz8RxmZzF5
|
22
|
+
6NVqFLbuqSRSU5U//WJvZVJt8dycCGgQzBM4Vi3nkOWyjIF0BANf1TqnlU2u6s8d
|
23
|
+
UK1AoDZfg5feef5e8eqoomHebX1opNGM/SOQhu3LRgax4rJfnl6VS3I2wighohsf
|
24
|
+
AgcCAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUGlrWBqxVieAPk7NEzBDp
|
25
|
+
kM+iAMMwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAJMoyBaJs8boiz
|
26
|
+
lFpbw6MWjk+7ZhqoHpFrWEV4nzb5GzyHZ7GU/pa1fSEQR0SCs+LnTLQbAYNQyUTT
|
27
|
+
O+UsTuA7xzI//v6cSodv3Q9NbfoDlou74xv1NXorWoosQFMpVWrXv+c/1RqU3cq4
|
28
|
+
WUr+rRiveEXG4tXOwkrpX8KH8xVp2vQZcGw3AXPqhzfqDGzpHd6ws3lk+8HoSrSo
|
29
|
+
2L68tDoxraF2Z2toAg9vfFw1+mOeDk1xVIPVcBy3tJxstHfHGHlQuMiRiDQX2b2D
|
30
|
+
YYU8UWVt2841IwB5Dgl4O+atXhe9ZTBO0W32pl4Bq5CP9lhQRT1KL7sxfznJlF7Y
|
31
|
+
BH3YFsdk
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
|
34
|
+
date: 2011-04-17 00:00:00 +02:00
|
35
|
+
default_executable:
|
36
|
+
dependencies:
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rspec
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.0.0
|
46
|
+
type: :development
|
47
|
+
version_requirements: *id001
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: active_record
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id002
|
59
|
+
description: Rails gem allowing ActiveRecord models to have order and to move them up and down
|
60
|
+
email: maciej@mensfeld.pl
|
61
|
+
executables: []
|
62
|
+
|
63
|
+
extensions: []
|
64
|
+
|
65
|
+
extra_rdoc_files:
|
66
|
+
- CHANGELOG.rdoc
|
67
|
+
- README.md
|
68
|
+
- lib/acts_as_orderable.rb
|
69
|
+
files:
|
70
|
+
- CHANGELOG.rdoc
|
71
|
+
- Gemfile
|
72
|
+
- MIT-LICENSE
|
73
|
+
- Manifest
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- init.rb
|
77
|
+
- lib/acts_as_orderable.rb
|
78
|
+
- spec/acts_as_orderable_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
- acts_as_orderable.gemspec
|
81
|
+
has_rdoc: true
|
82
|
+
homepage: https://github.com/mensfeld/Acts-as-Orderable
|
83
|
+
licenses: []
|
84
|
+
|
85
|
+
post_install_message:
|
86
|
+
rdoc_options:
|
87
|
+
- --line-numbers
|
88
|
+
- --inline-source
|
89
|
+
- --title
|
90
|
+
- Acts_as_orderable
|
91
|
+
- --main
|
92
|
+
- README.md
|
93
|
+
require_paths:
|
94
|
+
- lib
|
95
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
96
|
+
none: false
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: "0"
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: "1.2"
|
107
|
+
requirements: []
|
108
|
+
|
109
|
+
rubyforge_project: acts_as_orderable
|
110
|
+
rubygems_version: 1.5.2
|
111
|
+
signing_key:
|
112
|
+
specification_version: 3
|
113
|
+
summary: Rails gem allowing ActiveRecord models to have order and to move them up and down
|
114
|
+
test_files: []
|
115
|
+
|
metadata.gz.sig
ADDED