ranked-model 0.4.5 → 0.4.6

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.
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