ranked-model 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c342543b3341c81d62ceca340fc0966a3386a6115fc2ee36f309582995f8af52
4
- data.tar.gz: 25408af509201219ce0539dbfe3324c8b3806bce367d3e00b80a2f15dc6e7dc4
3
+ metadata.gz: 608245c9f9eeed1d195c18efd1df0b32d5593465d581f269e20fb8b8867a1260
4
+ data.tar.gz: 83a935d3b960f7acf48ada59f9e87962ab04b40d75c9af50b3ddf5dc6c5dfe5b
5
5
  SHA512:
6
- metadata.gz: 139bcf7c985b68e017e03bb3718a4377ec878ec7b249ac32ad20900d1467e5026a093e82725f8e39e1d8a378a7db0959f6a37f7571d1bccae40e9b8f70244a55
7
- data.tar.gz: ca739746fb067e6de9ae52bcb08f352fcdf676a02063e04f5d3b5f3b8a54d773ff57227d5dc5fca7c6d402155920b3da39c73d83d495680ff988f67248fac321
6
+ metadata.gz: 9ea50e38ff89431cfcf314144141f44b7aec03dc91aa8d45db24975f2a191bc0457c032511a8cc798fc10646ca29e8e35c011dcaed5adbf0d1344bb84e5469ef
7
+ data.tar.gz: 9e2d0cadcc12b87d1602d40ef0eb8a6e2f23eff6270a841ffcdd2cd06ed74b49d40e8bfd9c49ace0680f08b73f06a3980de413aec425e2104b16fa5b5a9b7e71
data/Appraisals CHANGED
@@ -4,6 +4,7 @@ appraise "rails-4-2" do
4
4
  end
5
5
  group :mysql do
6
6
  gem "mysql2", "~> 0.4.0", platform: :ruby
7
+ gem "jdbc-mysql", "~> 5.1.47", platform: :jruby
7
8
  gem "activerecord-jdbcmysql-adapter", "~> 1.3.24", platform: :jruby
8
9
  end
9
10
  group :postgresql do
@@ -16,6 +16,7 @@ end
16
16
 
17
17
  group :mysql do
18
18
  gem "mysql2", "~> 0.4.0", platform: :ruby
19
+ gem "jdbc-mysql", "~> 5.1.47", platform: :jruby
19
20
  gem "activerecord-jdbcmysql-adapter", "~> 1.3.24", platform: :jruby
20
21
  end
21
22
 
@@ -69,6 +69,10 @@ module RankedModel
69
69
  update_all(ranker.column => value)
70
70
  end
71
71
 
72
+ def reset_ranks!
73
+ finder.update_all(ranker.column => nil)
74
+ end
75
+
72
76
  def position
73
77
  instance.send "#{ranker.name}_position"
74
78
  end
@@ -209,31 +213,35 @@ module RankedModel
209
213
  end
210
214
 
211
215
  def rebalance_ranks
212
- if rank && instance.persisted?
213
- origin = current_order.index { |item| item.instance.id == instance.id }
214
- if origin
215
- destination = current_order.index { |item| rank <= item.rank }
216
- destination -= 1 if origin < destination
217
-
218
- current_order.insert destination, current_order.delete_at(origin)
216
+ ActiveRecord::Base.transaction do
217
+ if rank && instance.persisted?
218
+ origin = current_order.index { |item| item.instance.id == instance.id }
219
+ if origin
220
+ destination = current_order.index { |item| rank <= item.rank }
221
+ destination -= 1 if origin < destination
222
+
223
+ current_order.insert destination, current_order.delete_at(origin)
224
+ end
219
225
  end
220
- end
221
226
 
222
- gaps = current_order.size + 1
223
- range = (RankedModel::MAX_RANK_VALUE - RankedModel::MIN_RANK_VALUE).to_f
224
- gap_size = (range / gaps).ceil
227
+ gaps = current_order.size + 1
228
+ range = (RankedModel::MAX_RANK_VALUE - RankedModel::MIN_RANK_VALUE).to_f
229
+ gap_size = (range / gaps).ceil
225
230
 
226
- current_order.each.with_index(1) do |item, position|
227
- new_rank = (gap_size * position) + RankedModel::MIN_RANK_VALUE
231
+ reset_ranks!
228
232
 
229
- if item.instance.id == instance.id
230
- rank_at new_rank
231
- else
232
- item.update_rank! new_rank
233
+ current_order.each.with_index(1) do |item, position|
234
+ new_rank = (gap_size * position) + RankedModel::MIN_RANK_VALUE
235
+
236
+ if item.instance.id == instance.id
237
+ rank_at new_rank
238
+ else
239
+ item.update_rank! new_rank
240
+ end
233
241
  end
234
- end
235
242
 
236
- reset_cache
243
+ reset_cache
244
+ end
237
245
  end
238
246
 
239
247
  def finder(order = :asc)
@@ -1,3 +1,3 @@
1
1
  module RankedModel
2
- VERSION = "0.4.5"
2
+ VERSION = "0.4.6"
3
3
  end
@@ -780,33 +780,41 @@ describe Duck do
780
780
  end
781
781
 
782
782
  describe "when moving between ponds should work when rebalancing" do
783
-
784
- before {
783
+ before do
785
784
  [:feathers, :wingy, :webby, :waddly, :beaky].each_with_index do |name, i|
786
- Duck.where(id: @ducks[name].id).update_all(age: RankedModel::MIN_RANK_VALUE + i, pond: "Boyden")
787
- @ducks[name].reload
785
+ Duck.where(id: @ducks[name].id)
786
+ .update_all(age: RankedModel::MIN_RANK_VALUE + i, pond: "Boyden")
788
787
  end
789
788
 
790
- Duck.find_by(id: @ducks[:quacky]).update!(age_position: 2, pond: "Boyden")
791
- }
792
-
793
- context {
794
- subject { Duck.find_by(id: @ducks[:feathers]).age_rank }
795
-
796
- it { should == 0 }
797
- }
798
-
799
- context {
800
- subject { Duck.find_by(id: @ducks[:quacky]).age_rank }
789
+ @ducks[:quacky].update!(age_position: 2, pond: "Boyden")
790
+ end
801
791
 
802
- it { should == 2 }
803
- }
792
+ it 'rebalances ranks correctly' do
793
+ expect(@ducks[:feathers].reload.age_rank).to eq 0
794
+ expect(@ducks[:quacky].reload.age_rank).to eq 2
795
+ expect(@ducks[:beaky].reload.age_rank).to eq 5
796
+ end
804
797
 
805
- context {
806
- subject { Duck.find_by(id: @ducks[:beaky]).age_rank }
798
+ context 'when attempting to update position to a non-unique value' do
799
+ before do
800
+ @duck_one = Duck.create(landing_order: RankedModel::MIN_RANK_VALUE,
801
+ lake_id: 42, flock_id: 42)
802
+ # Duck one's landing order will be rebalanced to -715_827_883.
803
+ # Given a unique index on [:landing_order, :lake_id, :flock_id] we
804
+ # verify that the operation succeeds despite the value already being
805
+ # occupied by duck two.
806
+ @duck_two = Duck.create(landing_order: -715_827_883,
807
+ lake_id: 42, flock_id: 42)
808
+ end
807
809
 
808
- it { should == 5 }
809
- }
810
+ it 'rebalances ranks correctly' do
811
+ @ducks[:quacky].update!(landing_order_position: :first,
812
+ lake_id: 42, flock_id: 42)
813
+ expect(@ducks[:quacky].reload.landing_order_rank).to eq 0
814
+ expect(@duck_one.reload.landing_order_rank).to eq 1
815
+ expect(@duck_two.reload.landing_order_rank).to eq 2
816
+ end
817
+ end
810
818
  end
811
819
 
812
820
  end
@@ -5,7 +5,7 @@ describe Duck do
5
5
  before {
6
6
  200.times do |i|
7
7
  Duck.create \
8
- :name => "Duck #{i}"
8
+ :name => "Duck #{i + 1}"
9
9
  end
10
10
  }
11
11
 
@@ -149,34 +149,30 @@ describe Duck do
149
149
 
150
150
  describe "with no more gaps" do
151
151
 
152
- before {
152
+ before do
153
153
  @first = Duck.rank(:row).first
154
154
  @second = Duck.rank(:row).offset(1).first
155
155
  @third = Duck.rank(:row).offset(2).first
156
- @fourth = Duck.rank(:row).offset(4).first
157
- @fifth = Duck.rank(:row).offset(5).first
156
+ @fourth = Duck.rank(:row).offset(3).first
158
157
  @lower = Duck.rank(:row).
159
- where(Duck.arel_table[:id].not_in([@first.id, @second.id, @third.id, @fourth.id, @fifth.id])).
158
+ where(Duck.arel_table[:id].not_in([@first.id, @second.id, @third.id, @fourth.id])).
160
159
  where(Duck.arel_table[:row].lt(RankedModel::MAX_RANK_VALUE / 2)).
161
- collect {|d| d.id }
160
+ pluck(:id)
162
161
  @upper = Duck.rank(:row).
163
- where(Duck.arel_table[:id].not_in([@first.id, @second.id, @third.id, @fourth.id, @fifth.id])).
162
+ where(Duck.arel_table[:id].not_in([@first.id, @second.id, @third.id, @fourth.id])).
164
163
  where(Duck.arel_table[:row].gteq(RankedModel::MAX_RANK_VALUE / 2)).
165
- collect {|d| d.id }
166
- @first.update :row => RankedModel::MIN_RANK_VALUE
167
- @second.update :row => RankedModel::MAX_RANK_VALUE
168
- @third.update :row => (RankedModel::MAX_RANK_VALUE / 2)
169
- Duck.where(id: @fifth.id).update_all row: @third.row
170
- @fourth.update :row => @third.row
171
- }
172
-
173
- context {
174
-
175
- subject { Duck.rank(:row).collect {|d| d.id } }
176
-
177
- it { is_expected.to eq([@first.id] + @lower + [@fourth.id, @third.id, @fifth.id] + @upper + [@second.id]) }
178
-
179
- }
164
+ pluck(:id)
165
+ @first.update(row: RankedModel::MIN_RANK_VALUE)
166
+ @second.update(row: RankedModel::MAX_RANK_VALUE)
167
+ @third.update(row: (RankedModel::MAX_RANK_VALUE / 2))
168
+ @fourth.update(row: @third.row)
169
+ end
170
+
171
+ it 'works correctly' do
172
+ result = Duck.rank(:row).pluck(:id)
173
+ expected = [@first.id, *@lower, @fourth.id, @third.id, *@upper, @second.id]
174
+ expect(result).to eq(expected)
175
+ end
180
176
 
181
177
  end
182
178
 
@@ -21,6 +21,8 @@ ActiveRecord::Schema.define :version => 0 do
21
21
  t.string :pond
22
22
  end
23
23
 
24
+ add_index :ducks, [:landing_order, :lake_id, :flock_id], unique: true
25
+
24
26
  create_table :wrong_scope_ducks, :force => true do |t|
25
27
  t.string :name
26
28
  t.integer :size
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ranked-model
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Beale
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-21 00:00:00.000000000 Z
11
+ date: 2020-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord