ranked-model 0.0.4 → 0.0.5
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/lib/ranked-model/ranker.rb +32 -8
- data/lib/ranked-model/version.rb +1 -1
- data/spec/duck-model/duck_spec.rb +81 -0
- data/spec/sti-model/element_spec.rb +41 -0
- data/spec/support/active_record.rb +6 -0
- metadata +11 -13
data/lib/ranked-model/ranker.rb
CHANGED
@@ -34,8 +34,17 @@ module RankedModel
|
|
34
34
|
raise RankedModel::InvalidScope, %Q{No scope called "#{ranker.scope}" found in model}
|
35
35
|
end
|
36
36
|
|
37
|
-
if ranker.with_same
|
38
|
-
|
37
|
+
if ranker.with_same
|
38
|
+
if (case ranker.with_same
|
39
|
+
when Symbol
|
40
|
+
!instance.respond_to?(ranker.with_same)
|
41
|
+
when Array
|
42
|
+
ranker.with_same.detect {|attr| !instance.respond_to?(attr) }
|
43
|
+
else
|
44
|
+
false
|
45
|
+
end)
|
46
|
+
raise RankedModel::InvalidField, %Q{No field called "#{ranker.with_same}" found in model}
|
47
|
+
end
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
@@ -128,17 +137,17 @@ module RankedModel
|
|
128
137
|
end
|
129
138
|
|
130
139
|
def rearrange_ranks
|
131
|
-
if current_first.rank > RankedModel::MIN_RANK_VALUE && rank == RankedModel::MAX_RANK_VALUE
|
140
|
+
if current_first.rank && current_first.rank > RankedModel::MIN_RANK_VALUE && rank == RankedModel::MAX_RANK_VALUE
|
132
141
|
instance.class.
|
133
142
|
where( instance.class.arel_table[:id].not_eq(instance.id) ).
|
134
143
|
where( instance.class.arel_table[ranker.column].lteq(rank) ).
|
135
144
|
update_all( "#{ranker.column} = #{ranker.column} - 1" )
|
136
|
-
elsif current_last.rank < (RankedModel::MAX_RANK_VALUE - 1) && rank < current_last.rank
|
145
|
+
elsif current_last.rank && current_last.rank < (RankedModel::MAX_RANK_VALUE - 1) && rank < current_last.rank
|
137
146
|
instance.class.
|
138
147
|
where( instance.class.arel_table[:id].not_eq(instance.id) ).
|
139
148
|
where( instance.class.arel_table[ranker.column].gteq(rank) ).
|
140
149
|
update_all( "#{ranker.column} = #{ranker.column} + 1" )
|
141
|
-
elsif current_first.rank > RankedModel::MIN_RANK_VALUE && rank > current_first.rank
|
150
|
+
elsif current_first.rank && current_first.rank > RankedModel::MIN_RANK_VALUE && rank > current_first.rank
|
142
151
|
instance.class.
|
143
152
|
where( instance.class.arel_table[:id].not_eq(instance.id) ).
|
144
153
|
where( instance.class.arel_table[ranker.column].lt(rank) ).
|
@@ -177,9 +186,24 @@ module RankedModel
|
|
177
186
|
if ranker.scope
|
178
187
|
_finder = _finder.send ranker.scope
|
179
188
|
end
|
180
|
-
|
181
|
-
|
182
|
-
|
189
|
+
case ranker.with_same
|
190
|
+
when Symbol
|
191
|
+
_finder = _finder.where \
|
192
|
+
instance.class.arel_table[ranker.with_same].eq(instance.attributes["#{ranker.with_same}"])
|
193
|
+
when Array
|
194
|
+
_finder = _finder.where(
|
195
|
+
ranker.with_same[1..-1].inject(
|
196
|
+
instance.class.arel_table[ranker.with_same.first].eq(
|
197
|
+
instance.attributes["#{ranker.with_same.first}"]
|
198
|
+
)
|
199
|
+
) {|scoper, attr|
|
200
|
+
scoper.and(
|
201
|
+
instance.class.arel_table[attr].eq(
|
202
|
+
instance.attributes["#{attr}"]
|
203
|
+
)
|
204
|
+
)
|
205
|
+
}
|
206
|
+
)
|
183
207
|
end
|
184
208
|
if !new_record?
|
185
209
|
_finder = _finder.where \
|
data/lib/ranked-model/version.rb
CHANGED
@@ -14,6 +14,8 @@ describe Duck do
|
|
14
14
|
it { subject.respond_to?(:size_position=).should be_true }
|
15
15
|
it { subject.respond_to?(:age_position).should be_true }
|
16
16
|
it { subject.respond_to?(:age_position=).should be_true }
|
17
|
+
it { subject.respond_to?(:landing_order_position).should be_true }
|
18
|
+
it { subject.respond_to?(:landing_order_position=).should be_true }
|
17
19
|
|
18
20
|
end
|
19
21
|
|
@@ -288,3 +290,82 @@ describe Duck do
|
|
288
290
|
end
|
289
291
|
|
290
292
|
end
|
293
|
+
|
294
|
+
describe Duck do
|
295
|
+
|
296
|
+
before {
|
297
|
+
@ducks = {
|
298
|
+
:quacky => Duck.create(
|
299
|
+
:name => 'Quacky',
|
300
|
+
:lake_id => 0,
|
301
|
+
:flock_id => 0 ),
|
302
|
+
:feathers => Duck.create(
|
303
|
+
:name => 'Feathers',
|
304
|
+
:lake_id => 0,
|
305
|
+
:flock_id => 0 ),
|
306
|
+
:wingy => Duck.create(
|
307
|
+
:name => 'Wingy',
|
308
|
+
:lake_id => 0,
|
309
|
+
:flock_id => 0 ),
|
310
|
+
:webby => Duck.create(
|
311
|
+
:name => 'Webby',
|
312
|
+
:lake_id => 1,
|
313
|
+
:flock_id => 1 ),
|
314
|
+
:waddly => Duck.create(
|
315
|
+
:name => 'Waddly',
|
316
|
+
:lake_id => 1,
|
317
|
+
:flock_id => 0 ),
|
318
|
+
:beaky => Duck.create(
|
319
|
+
:name => 'Beaky',
|
320
|
+
:lake_id => 0,
|
321
|
+
:flock_id => 1 ),
|
322
|
+
}
|
323
|
+
@ducks.each { |name, duck|
|
324
|
+
duck.reload
|
325
|
+
duck.update_attribute :landing_order_position, 0
|
326
|
+
duck.save!
|
327
|
+
}
|
328
|
+
@ducks.each {|name, duck| duck.reload }
|
329
|
+
}
|
330
|
+
|
331
|
+
describe "sorting by landing_order" do
|
332
|
+
|
333
|
+
before {
|
334
|
+
@ducks[:quacky].update_attribute :landing_order_position, 0
|
335
|
+
@ducks[:wingy].update_attribute :landing_order_position, 1
|
336
|
+
}
|
337
|
+
|
338
|
+
subject { Duck.in_lake_and_flock(0,0).rank(:landing_order).all }
|
339
|
+
|
340
|
+
its(:size) { should == 3 }
|
341
|
+
|
342
|
+
its(:first) { should == @ducks[:quacky] }
|
343
|
+
|
344
|
+
its(:last) { should == @ducks[:feathers] }
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
describe "sorting by landing_order doesn't touch other items" do
|
349
|
+
|
350
|
+
before {
|
351
|
+
@untouchable_ranks = lambda {
|
352
|
+
[:webby, :waddly, :beaky].inject([]) do |ranks, untouchable_duck|
|
353
|
+
ranks << @ducks[untouchable_duck].landing_order
|
354
|
+
end
|
355
|
+
}
|
356
|
+
|
357
|
+
@previous_ranks = @untouchable_ranks.call
|
358
|
+
|
359
|
+
@ducks[:quacky].update_attribute :landing_order_position, 0
|
360
|
+
@ducks[:wingy].update_attribute :landing_order_position, 1
|
361
|
+
@ducks[:feathers].update_attribute :landing_order_position, 0
|
362
|
+
@ducks[:wingy].update_attribute :landing_order_position, 1
|
363
|
+
}
|
364
|
+
|
365
|
+
subject { @untouchable_ranks.call }
|
366
|
+
|
367
|
+
it { should == @previous_ranks }
|
368
|
+
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
@@ -78,4 +78,45 @@ describe Element do
|
|
78
78
|
|
79
79
|
end
|
80
80
|
|
81
|
+
describe "setting positions on STI classes" do
|
82
|
+
|
83
|
+
before {
|
84
|
+
@elements[:helium].update_attribute :combination_order_position, :first
|
85
|
+
@elements[:xenon].update_attribute :combination_order_position, :first
|
86
|
+
@elements[:argon].update_attribute :combination_order_position, :first
|
87
|
+
|
88
|
+
@elements[:chromium].update_attribute :combination_order_position, 1
|
89
|
+
@elements[:manganese].update_attribute :combination_order_position, 1
|
90
|
+
@elements[:manganese].update_attribute :combination_order_position, 0
|
91
|
+
@elements[:chromium].update_attribute :combination_order_position, 0
|
92
|
+
@elements[:manganese].update_attribute :combination_order_position, 0
|
93
|
+
@elements[:chromium].update_attribute :combination_order_position, 0
|
94
|
+
}
|
95
|
+
|
96
|
+
describe "NobleGas" do
|
97
|
+
|
98
|
+
subject { NobleGas.rank(:combination_order) }
|
99
|
+
|
100
|
+
its(:size) { should == 3 }
|
101
|
+
|
102
|
+
its(:first) { should == @elements[:argon] }
|
103
|
+
|
104
|
+
its(:last) { should == @elements[:helium] }
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "TransitionMetal" do
|
109
|
+
|
110
|
+
subject { TransitionMetal.rank(:combination_order) }
|
111
|
+
|
112
|
+
its(:size) { should == 2 }
|
113
|
+
|
114
|
+
its(:first) { should == @elements[:chromium] }
|
115
|
+
|
116
|
+
its(:last) { should == @elements[:manganese] }
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
81
122
|
end
|
@@ -16,6 +16,9 @@ ActiveRecord::Schema.define :version => 0 do
|
|
16
16
|
t.integer :row
|
17
17
|
t.integer :size
|
18
18
|
t.integer :age
|
19
|
+
t.integer :lake_id
|
20
|
+
t.integer :flock_id
|
21
|
+
t.integer :landing_order
|
19
22
|
t.string :pond
|
20
23
|
end
|
21
24
|
|
@@ -44,6 +47,9 @@ class Duck < ActiveRecord::Base
|
|
44
47
|
ranks :row
|
45
48
|
ranks :size, :scope => :in_shin_pond
|
46
49
|
ranks :age, :with_same => :pond
|
50
|
+
|
51
|
+
ranks :landing_order, :with_same => [:lake_id, :flock_id]
|
52
|
+
scope :in_lake_and_flock, lambda {|lake, flock| where(:lake_id => lake, :flock_id => flock) }
|
47
53
|
|
48
54
|
scope :in_shin_pond, where(:pond => 'Shin')
|
49
55
|
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ranked-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Matthew Beale
|
@@ -15,11 +15,9 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
19
|
-
default_executable:
|
18
|
+
date: 2011-08-22 00:00:00 Z
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
22
|
-
name: activerecord
|
23
21
|
prerelease: false
|
24
22
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
23
|
none: false
|
@@ -34,8 +32,8 @@ dependencies:
|
|
34
32
|
version: 3.0.3
|
35
33
|
type: :runtime
|
36
34
|
version_requirements: *id001
|
35
|
+
name: activerecord
|
37
36
|
- !ruby/object:Gem::Dependency
|
38
|
-
name: rspec
|
39
37
|
prerelease: false
|
40
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
39
|
none: false
|
@@ -48,8 +46,8 @@ dependencies:
|
|
48
46
|
version: "0"
|
49
47
|
type: :development
|
50
48
|
version_requirements: *id002
|
49
|
+
name: rspec
|
51
50
|
- !ruby/object:Gem::Dependency
|
52
|
-
name: rspec-rails
|
53
51
|
prerelease: false
|
54
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
55
53
|
none: false
|
@@ -62,8 +60,8 @@ dependencies:
|
|
62
60
|
version: "0"
|
63
61
|
type: :development
|
64
62
|
version_requirements: *id003
|
63
|
+
name: rspec-rails
|
65
64
|
- !ruby/object:Gem::Dependency
|
66
|
-
name: sqlite3
|
67
65
|
prerelease: false
|
68
66
|
requirement: &id004 !ruby/object:Gem::Requirement
|
69
67
|
none: false
|
@@ -76,8 +74,8 @@ dependencies:
|
|
76
74
|
version: "0"
|
77
75
|
type: :development
|
78
76
|
version_requirements: *id004
|
77
|
+
name: sqlite3
|
79
78
|
- !ruby/object:Gem::Dependency
|
80
|
-
name: genspec
|
81
79
|
prerelease: false
|
82
80
|
requirement: &id005 !ruby/object:Gem::Requirement
|
83
81
|
none: false
|
@@ -90,8 +88,8 @@ dependencies:
|
|
90
88
|
version: "0"
|
91
89
|
type: :development
|
92
90
|
version_requirements: *id005
|
91
|
+
name: genspec
|
93
92
|
- !ruby/object:Gem::Dependency
|
94
|
-
name: mocha
|
95
93
|
prerelease: false
|
96
94
|
requirement: &id006 !ruby/object:Gem::Requirement
|
97
95
|
none: false
|
@@ -104,6 +102,7 @@ dependencies:
|
|
104
102
|
version: "0"
|
105
103
|
type: :development
|
106
104
|
version_requirements: *id006
|
105
|
+
name: mocha
|
107
106
|
description: ranked-model is a modern row sorting library built for Rails 3. It uses ARel aggressively and is better optimized than most other libraries.
|
108
107
|
email:
|
109
108
|
- matt.beale@madhatted.com
|
@@ -136,7 +135,6 @@ files:
|
|
136
135
|
- spec/support/active_record.rb
|
137
136
|
- spec/support/database.yml
|
138
137
|
- tmp/.gitignore
|
139
|
-
has_rdoc: true
|
140
138
|
homepage: https://github.com/harvesthq/ranked-model
|
141
139
|
licenses: []
|
142
140
|
|
@@ -166,7 +164,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
164
|
requirements: []
|
167
165
|
|
168
166
|
rubyforge_project:
|
169
|
-
rubygems_version: 1.
|
167
|
+
rubygems_version: 1.8.8
|
170
168
|
signing_key:
|
171
169
|
specification_version: 3
|
172
170
|
summary: An acts_as_sortable replacement built for Rails 3
|