resort 0.0.2 → 0.2.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/.gitignore +1 -0
- data/Readme.md +12 -14
- data/lib/generators/active_record/resort_generator.rb +30 -0
- data/lib/generators/active_record/templates/migration.rb +17 -0
- data/lib/resort/version.rb +1 -1
- data/lib/resort.rb +38 -27
- data/resort.gemspec +1 -0
- data/spec/generators/migration_spec.rb +38 -0
- data/spec/resort_spec.rb +133 -28
- data/spec/spec_helper.rb +35 -0
- metadata +17 -2
data/.gitignore
CHANGED
data/Readme.md
CHANGED
@@ -23,21 +23,10 @@ references a `next` element, which seems a bit more sensible :)
|
|
23
23
|
|
24
24
|
##Usage
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
class AddResortFieldsToProducts < ActiveRecord::Migration
|
29
|
-
def self.up
|
30
|
-
add_column :products, :next_id, :integer
|
31
|
-
add_column :products, :first, :boolean
|
32
|
-
add_index :products, :next_id
|
33
|
-
add_index :products, :first
|
34
|
-
end
|
26
|
+
First, run the migration for the model you want to Resort:
|
35
27
|
|
36
|
-
|
37
|
-
|
38
|
-
remove_column :products, :first
|
39
|
-
end
|
40
|
-
end
|
28
|
+
$ rails generate resort:migration product
|
29
|
+
$ rake db:migrate
|
41
30
|
|
42
31
|
Then in your Product model:
|
43
32
|
|
@@ -57,6 +46,15 @@ separate tree of sortable products, you must override the `siblings` method:
|
|
57
46
|
self.product_line.products
|
58
47
|
end
|
59
48
|
end
|
49
|
+
|
50
|
+
### Concurrency
|
51
|
+
|
52
|
+
Multiple users modifying the same list at the same time could be a problem,
|
53
|
+
so it's always a good practice to wrap the changes in a transaction:
|
54
|
+
|
55
|
+
Product.transaction do
|
56
|
+
my_product.append_to(another_product)
|
57
|
+
end
|
60
58
|
|
61
59
|
###API
|
62
60
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module Resort
|
5
|
+
# Module containing Resort generators
|
6
|
+
module Generators
|
7
|
+
|
8
|
+
# Rails generator to add a migration for Resort
|
9
|
+
class MigrationGenerator < ActiveRecord::Generators::Base
|
10
|
+
# Implement the required interface for `Rails::Generators::Migration`.
|
11
|
+
# Taken from `ActiveRecord` code.
|
12
|
+
# @see http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
|
13
|
+
def self.next_migration_number(dirname)
|
14
|
+
if ActiveRecord::Base.timestamped_migrations
|
15
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
16
|
+
else
|
17
|
+
"%.3d" % (current_migration_number(dirname) + 1)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Creates a Resort migration."
|
22
|
+
source_root File.expand_path("../templates", __FILE__)
|
23
|
+
|
24
|
+
# Copies a migration file adding resort fields to a given model
|
25
|
+
def copy_migration_file
|
26
|
+
migration_template 'migration.rb', "db/migrate/add_resort_fields_to_#{table_name.pluralize}.rb"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# Migration to add the necessary fields to a resorted model
|
2
|
+
class AddResortFieldsTo<%= table_name.camelize %> < ActiveRecord::Migration
|
3
|
+
# Adds Resort fields, next_id and first, and indexes to a given model
|
4
|
+
def self.up
|
5
|
+
add_column :<%= table_name %>, :next_id, :integer
|
6
|
+
add_column :<%= table_name %>, :first, :boolean
|
7
|
+
add_index :<%= table_name %>, :next_id
|
8
|
+
add_index :<%= table_name %>, :first
|
9
|
+
end
|
10
|
+
|
11
|
+
# Removes Resort fields
|
12
|
+
def self.down
|
13
|
+
remove_column :<%= table_name %>, :next_id
|
14
|
+
remove_column :<%= table_name %>, :first
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
data/lib/resort/version.rb
CHANGED
data/lib/resort.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'generators/active_record/resort_generator' if defined?(Rails)
|
2
|
+
|
1
3
|
# # Resort
|
2
4
|
#
|
3
5
|
# A tool that allows any ActiveRecord model to be sorted.
|
@@ -71,12 +73,20 @@ module Resort
|
|
71
73
|
#
|
72
74
|
# @return [ActiveRecord::Base] the first element of the list.
|
73
75
|
def first_in_order
|
74
|
-
where(:first => true).first
|
76
|
+
scoped.where(:first => true).first
|
77
|
+
end
|
78
|
+
|
79
|
+
# Returns the last element of the list.
|
80
|
+
#
|
81
|
+
# @return [ActiveRecord::Base] the last element of the list.
|
82
|
+
def last_in_order
|
83
|
+
scoped.where(:next_id => nil).first
|
75
84
|
end
|
85
|
+
|
76
86
|
|
77
87
|
# Returns eager-loaded Components in order.
|
78
88
|
#
|
79
|
-
# OPTIMIZE:
|
89
|
+
# OPTIMIZE: Use IdentityMap when available
|
80
90
|
# @return [Array<ActiveRecord::Base>] the ordered elements
|
81
91
|
def ordered
|
82
92
|
ordered_elements = []
|
@@ -90,10 +100,12 @@ module Resort
|
|
90
100
|
end
|
91
101
|
end
|
92
102
|
|
103
|
+
raise "Multiple or no first items in the list where found. Consider defining a siblings method" if ordered_elements.length != 1 && elements.length > 0
|
104
|
+
|
93
105
|
elements.length.times do
|
94
106
|
ordered_elements << elements[ordered_elements.last.next_id]
|
95
107
|
end
|
96
|
-
ordered_elements
|
108
|
+
ordered_elements.compact
|
97
109
|
end
|
98
110
|
end
|
99
111
|
|
@@ -146,47 +158,46 @@ module Resort
|
|
146
158
|
|
147
159
|
# Puts the object in the last position of the list.
|
148
160
|
def push
|
149
|
-
self.append_to(
|
161
|
+
self.append_to(_siblings.last_in_order) unless last?
|
150
162
|
end
|
151
163
|
|
152
164
|
# Puts the object right after another object in the list.
|
153
165
|
def append_to(another)
|
154
|
-
if
|
155
|
-
delete_from_list
|
156
|
-
elsif last? && self.previous
|
157
|
-
# self.previous.update_attribute(:next_id, nil)
|
158
|
-
self.previous = nil
|
159
|
-
end
|
166
|
+
return if another.next_id == id
|
160
167
|
|
161
|
-
|
162
|
-
|
168
|
+
delete_from_list
|
169
|
+
|
170
|
+
self.class.transaction do
|
171
|
+
self.update_attribute(:next_id, another.next_id) if self.next_id or (another && another.next_id)
|
172
|
+
another.update_attribute(:next_id, self.id) if another
|
173
|
+
end
|
163
174
|
end
|
164
175
|
|
165
176
|
private
|
166
177
|
|
167
178
|
def delete_from_list
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
self.
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
179
|
+
self.class.transaction do
|
180
|
+
if first? && self.next
|
181
|
+
self.next.update_attribute(:first, true)
|
182
|
+
elsif self.previous
|
183
|
+
self.previous.update_attribute(:next_id, self.next_id)
|
184
|
+
end
|
185
|
+
|
186
|
+
unless frozen?
|
187
|
+
self.first = false
|
188
|
+
self.next = nil
|
189
|
+
self.previous = nil
|
190
|
+
save!
|
191
|
+
end
|
177
192
|
end
|
178
193
|
end
|
179
194
|
|
180
195
|
def last?
|
181
|
-
self.first
|
182
|
-
end
|
183
|
-
|
184
|
-
def last
|
185
|
-
_siblings.where(:next_id => nil).first
|
196
|
+
!self.first && !self.next_id
|
186
197
|
end
|
187
198
|
|
188
199
|
def last!
|
189
|
-
|
200
|
+
_siblings.last_in_order.update_attribute(:next_id, self.id)
|
190
201
|
end
|
191
202
|
|
192
203
|
def _siblings
|
data/resort.gemspec
CHANGED
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.add_development_dependency 'rspec', '~> 2.5.0'
|
20
20
|
s.add_development_dependency 'yard'
|
21
21
|
s.add_development_dependency 'bluecloth'
|
22
|
+
s.add_development_dependency 'generator_spec', '~> 0.8.1'
|
22
23
|
|
23
24
|
s.files = `git ls-files`.split("\n")
|
24
25
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'action_controller'
|
3
|
+
require 'action_view'
|
4
|
+
ActionView::Template::Handlers::ERB::ENCODING_FLAG = ActionView::ENCODING_FLAG
|
5
|
+
require 'generator_spec/test_case'
|
6
|
+
|
7
|
+
module Resort
|
8
|
+
module Generators
|
9
|
+
describe MigrationGenerator do
|
10
|
+
include GeneratorSpec::TestCase
|
11
|
+
destination File.expand_path('../../../tmp', __FILE__)
|
12
|
+
tests MigrationGenerator
|
13
|
+
arguments %w(article)
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
prepare_destination
|
17
|
+
mkdir File.join(self.test_case.destination_root, 'config')
|
18
|
+
run_generator
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'generates Resort migration' do
|
22
|
+
destination_root.should have_structure {
|
23
|
+
|
24
|
+
directory "db" do
|
25
|
+
directory "migrate" do
|
26
|
+
migration "add_resort_fields_to_articles" do
|
27
|
+
contains "class AddResortFieldsToArticles"
|
28
|
+
contains ":articles, :next_id"
|
29
|
+
contains ":articles, :first"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/spec/resort_spec.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class Article < ActiveRecord::Base
|
4
|
-
resort!
|
5
|
-
end
|
6
|
-
|
7
3
|
module Resort
|
8
4
|
describe Sortable do
|
9
5
|
|
@@ -26,15 +22,8 @@ module Resort
|
|
26
22
|
end
|
27
23
|
|
28
24
|
describe 'ClassMethods' do
|
29
|
-
describe "#first_in_order" do
|
30
|
-
it 'returns the first element of the list' do
|
31
|
-
first = double :article
|
32
|
-
Article.should_receive(:where).with(:first => true).and_return [first]
|
33
25
|
|
34
|
-
|
35
|
-
end
|
36
|
-
end
|
37
|
-
describe "#ordered" do
|
26
|
+
describe "ordering" do
|
38
27
|
before do
|
39
28
|
Article.destroy_all
|
40
29
|
|
@@ -42,20 +31,85 @@ module Resort
|
|
42
31
|
Article.create(:name => i.to_s)
|
43
32
|
end
|
44
33
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
34
|
+
Article.find_by_name('0').append_to(Article.find_by_name('3'))
|
35
|
+
Article.find_by_name('1').append_to(Article.find_by_name('3'))
|
36
|
+
Article.find_by_name('2').append_to(Article.find_by_name('3'))
|
37
|
+
|
38
|
+
@article1 = Article.find_by_name('3')
|
39
|
+
@article2 = Article.find_by_name('2')
|
40
|
+
@article3 = Article.find_by_name('1')
|
41
|
+
@article4 = Article.find_by_name('0')
|
49
42
|
end
|
50
|
-
|
51
|
-
|
43
|
+
|
44
|
+
describe "#first_in_order" do
|
45
|
+
it 'returns the first element of the list' do
|
46
|
+
Article.first_in_order.should == @article1
|
47
|
+
end
|
52
48
|
end
|
49
|
+
|
50
|
+
describe "#last_in_order" do
|
51
|
+
it 'returns the last element of the list' do
|
52
|
+
Article.last_in_order.should == @article4
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe "#ordered" do
|
57
|
+
it 'returns all elements ordered' do
|
58
|
+
Article.ordered.should == [@article1, @article2, @article3, @article4]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
53
62
|
after do
|
54
63
|
Article.destroy_all
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
58
67
|
|
68
|
+
describe "siblings" do
|
69
|
+
before do
|
70
|
+
one_list = List.create(:name => 'My list')
|
71
|
+
another_list = List.create(:name => 'My other list')
|
72
|
+
|
73
|
+
4.times do |i|
|
74
|
+
one_list.items << ListItem.new(:name => "My list item #{i}")
|
75
|
+
another_list.items << ListItem.new(:name => "My other list item #{i}")
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
describe "#first_in_order" do
|
81
|
+
it 'returns the first element of the list' do
|
82
|
+
List.find_by_name('My list').items.first_in_order.name.should == "My list item 0"
|
83
|
+
List.find_by_name('My other list').items.first_in_order.name.should == "My other list item 0"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "#last_in_order" do
|
88
|
+
it 'returns the last element of the list' do
|
89
|
+
List.find_by_name('My list').items.last_in_order.name.should == "My list item 3"
|
90
|
+
List.find_by_name('My other list').items.last_in_order.name.should == "My other list item 3"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "#ordered" do
|
95
|
+
it 'returns all elements ordered' do
|
96
|
+
List.find_by_name('My list').items.ordered.map(&:name).should == ['My list item 0', 'My list item 1', 'My list item 2', 'My list item 3']
|
97
|
+
List.find_by_name('My other list').items.ordered.map(&:name).should == ['My other list item 0', 'My other list item 1', 'My other list item 2', 'My other list item 3']
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'raises when ordering without scope' do
|
101
|
+
expect {
|
102
|
+
ListItem.ordered
|
103
|
+
}.to raise_error
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
after do
|
108
|
+
List.destroy_all
|
109
|
+
ListItem.destroy_all
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
59
113
|
describe "after create" do
|
60
114
|
context 'when there are no siblings' do
|
61
115
|
it 'prepends the element' do
|
@@ -72,14 +126,54 @@ module Resort
|
|
72
126
|
Article.create(:name => 'last!')
|
73
127
|
|
74
128
|
article = Article.find_by_name('last!')
|
129
|
+
first = Article.find_by_name('1')
|
75
130
|
|
76
131
|
article.should be_last
|
132
|
+
article.next_id.should be_nil
|
77
133
|
article.previous.name.should == '1'
|
134
|
+
|
135
|
+
first.next_id.should eq(article.id)
|
78
136
|
end
|
79
137
|
end
|
80
138
|
after do
|
81
139
|
Article.destroy_all
|
82
140
|
end
|
141
|
+
|
142
|
+
context "with custom siblings" do
|
143
|
+
|
144
|
+
context 'when there are no siblings' do
|
145
|
+
it 'prepends the element' do
|
146
|
+
one_list = List.create(:name => 'My list')
|
147
|
+
another_list = List.create(:name => 'My other list')
|
148
|
+
item = ListItem.create(:name => "My list item", :list => one_list)
|
149
|
+
|
150
|
+
item.should be_first
|
151
|
+
item.next.should be_nil
|
152
|
+
item.previous.should be_nil
|
153
|
+
end
|
154
|
+
end
|
155
|
+
context 'otherwise' do
|
156
|
+
it 'appends the element' do
|
157
|
+
one_list = List.create(:name => 'My list')
|
158
|
+
another_list = List.create(:name => 'My other list')
|
159
|
+
ListItem.create(:name => "1", :list => one_list)
|
160
|
+
ListItem.create(:name => "last!", :list => one_list)
|
161
|
+
|
162
|
+
first = ListItem.find_by_name('1')
|
163
|
+
last = ListItem.find_by_name('last!')
|
164
|
+
|
165
|
+
last.should be_last
|
166
|
+
last.next_id.should be_nil
|
167
|
+
last.previous.name.should == '1'
|
168
|
+
|
169
|
+
first.next_id.should eq(last.id)
|
170
|
+
end
|
171
|
+
end
|
172
|
+
after do
|
173
|
+
List.destroy_all
|
174
|
+
ListItem.destroy_all
|
175
|
+
end
|
176
|
+
end
|
83
177
|
end
|
84
178
|
|
85
179
|
describe "after destroy" do
|
@@ -190,35 +284,43 @@ module Resort
|
|
190
284
|
it "appends the element after another element" do
|
191
285
|
@article1.append_to(@article2)
|
192
286
|
|
193
|
-
article2 = Article.find_by_name('2')
|
194
|
-
article2.next.name.should == '1'
|
195
|
-
|
196
287
|
article1 = Article.find_by_name('1')
|
197
288
|
article1.next.name.should == '3'
|
198
289
|
article1.previous.name.should == '2'
|
199
290
|
@article3.previous.name.should == '1'
|
291
|
+
end
|
292
|
+
|
293
|
+
it "sets the other element as first" do
|
294
|
+
@article1.append_to(@article2)
|
200
295
|
|
296
|
+
article2 = Article.find_by_name('2')
|
297
|
+
article2.next.name.should == '1'
|
201
298
|
article2.should be_first
|
202
299
|
end
|
203
300
|
end
|
301
|
+
|
204
302
|
context 'appending 1 after 3' do
|
205
303
|
it "appends the element after another element" do
|
206
304
|
@article1.append_to(@article3)
|
207
305
|
|
208
|
-
article2 = Article.find_by_name('2')
|
209
|
-
article2.should be_first
|
210
|
-
article2.previous.should be_nil
|
211
|
-
|
212
306
|
article1 = Article.find_by_name('1')
|
213
307
|
article1.should_not be_first
|
214
308
|
article1.previous.name.should == '3'
|
215
309
|
article1.next.name.should == '4'
|
216
310
|
|
217
311
|
@article3.next.name.should == '1'
|
218
|
-
|
219
312
|
@article4.previous.name.should == '1'
|
220
313
|
end
|
314
|
+
|
315
|
+
it 'resets the first element' do
|
316
|
+
@article1.append_to(@article3)
|
317
|
+
|
318
|
+
article2 = Article.find_by_name('2')
|
319
|
+
article2.should be_first
|
320
|
+
article2.previous.should be_nil
|
321
|
+
end
|
221
322
|
end
|
323
|
+
|
222
324
|
context 'appending 2 after 3' do
|
223
325
|
it "appends the element after another element" do
|
224
326
|
@article2.append_to(@article3)
|
@@ -290,8 +392,11 @@ module Resort
|
|
290
392
|
it 'does nothing' do
|
291
393
|
@article2.append_to(@article1)
|
292
394
|
|
293
|
-
|
294
|
-
|
395
|
+
article1 = Article.find_by_name('1')
|
396
|
+
article2 = Article.find_by_name('2')
|
397
|
+
|
398
|
+
article1.next.name.should == '2'
|
399
|
+
article2.previous.name.should == '1'
|
295
400
|
end
|
296
401
|
end
|
297
402
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require 'resort'
|
3
|
+
require 'logger'
|
3
4
|
|
4
5
|
ActiveRecord::Base.establish_connection(
|
5
6
|
:adapter => 'sqlite3',
|
@@ -16,4 +17,38 @@ ActiveRecord::Schema.define do
|
|
16
17
|
|
17
18
|
t.timestamps
|
18
19
|
end
|
20
|
+
|
21
|
+
create_table :lists do |t|
|
22
|
+
t.string :name
|
23
|
+
t.timestamps
|
24
|
+
end
|
25
|
+
|
26
|
+
create_table :list_items do |t|
|
27
|
+
t.string :name
|
28
|
+
t.boolean :first
|
29
|
+
t.references :next
|
30
|
+
t.references :list
|
31
|
+
t.timestamps
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# ActiveRecord::Base.logger = Logger.new(STDOUT)
|
36
|
+
|
37
|
+
class Article < ActiveRecord::Base
|
38
|
+
resort!
|
39
|
+
end
|
40
|
+
|
41
|
+
class List < ActiveRecord::Base
|
42
|
+
has_many :items, :class_name => 'ListItem'
|
43
|
+
end
|
44
|
+
|
45
|
+
class ListItem < ActiveRecord::Base
|
46
|
+
belongs_to :list
|
47
|
+
resort!
|
48
|
+
|
49
|
+
default_scope :order => 'created_at desc'
|
50
|
+
|
51
|
+
def siblings
|
52
|
+
self.list.items
|
53
|
+
end
|
19
54
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: resort
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0
|
5
|
+
version: 0.2.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Oriol Gual
|
@@ -12,7 +12,7 @@ autorequire:
|
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
14
|
|
15
|
-
date: 2011-03-
|
15
|
+
date: 2011-03-30 00:00:00 +02:00
|
16
16
|
default_executable:
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
@@ -70,6 +70,17 @@ dependencies:
|
|
70
70
|
version: "0"
|
71
71
|
type: :development
|
72
72
|
version_requirements: *id005
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: generator_spec
|
75
|
+
prerelease: false
|
76
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ~>
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: 0.8.1
|
82
|
+
type: :development
|
83
|
+
version_requirements: *id006
|
73
84
|
description: Positionless model sorting for Rails 3.
|
74
85
|
email:
|
75
86
|
- info@codegram.com
|
@@ -87,9 +98,12 @@ files:
|
|
87
98
|
- LICENSE
|
88
99
|
- Rakefile
|
89
100
|
- Readme.md
|
101
|
+
- lib/generators/active_record/resort_generator.rb
|
102
|
+
- lib/generators/active_record/templates/migration.rb
|
90
103
|
- lib/resort.rb
|
91
104
|
- lib/resort/version.rb
|
92
105
|
- resort.gemspec
|
106
|
+
- spec/generators/migration_spec.rb
|
93
107
|
- spec/resort_spec.rb
|
94
108
|
- spec/spec_helper.rb
|
95
109
|
has_rdoc: true
|
@@ -121,5 +135,6 @@ signing_key:
|
|
121
135
|
specification_version: 3
|
122
136
|
summary: Positionless model sorting for Rails 3.
|
123
137
|
test_files:
|
138
|
+
- spec/generators/migration_spec.rb
|
124
139
|
- spec/resort_spec.rb
|
125
140
|
- spec/spec_helper.rb
|