Skip to content

Commit b29b9ef

Browse files
authored
Merge pull request #27 from LukasSkywalker/main
Fix healer when model uses an ordering default scope
2 parents 0252882 + b43d1cc commit b29b9ef

File tree

6 files changed

+37
-2
lines changed

6 files changed

+37
-2
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
## [Unreleased]
22

3+
- Fix healing a list with a default scope `:order` and/or `:select`. Thanks @LukasSkywalker!
4+
35
## [0.4.4] - 2024-11-20
46

57
- Add `funding_uri` to gemspec.

lib/positioning/healer.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ def initialize(model, column, order)
88

99
def heal
1010
if scope_columns.present?
11-
@model.select(*scope_columns).distinct.each do |scope_record|
11+
@model.unscope(:order).reselect(*scope_columns).distinct.each do |scope_record|
1212
@model.transaction do
1313
if scope_associations.present?
1414
scope_associations.each do |scope_association|
@@ -40,7 +40,7 @@ def scope_associations
4040
end
4141

4242
def sequence(scope)
43-
scope.reorder(@order).each.with_index(1) do |record, index|
43+
scope.unscope(:select).reorder(@order).each.with_index(1) do |record, index|
4444
record.update_columns @column => index
4545
end
4646
end

test/models/default_scope_item.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class DefaultScopeItem < ActiveRecord::Base
2+
belongs_to :list
3+
4+
positioned on: :list
5+
6+
default_scope -> { select(:name, :position).order(:position) }
7+
end

test/models/list.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
class List < ActiveRecord::Base
22
has_many :items, -> { order(:position) }, dependent: :destroy
33
has_many :new_items, -> { order(:position) }, dependent: :destroy
4+
has_many :default_scope_items, -> { order(:position) }, dependent: :destroy
45
has_many :composite_primary_key_items, -> { order(:position) }, dependent: :destroy
56
has_many :authors, -> { order(:position) }, dependent: :destroy
67
end

test/support/active_record.rb

+8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@
3636
t.references :list, null: false
3737
end
3838

39+
create_table :default_scope_items, force: true do |t|
40+
t.string :name
41+
t.integer :position, null: false
42+
t.references :list, null: false
43+
end
44+
45+
add_index :default_scope_items, [:list_id, :position], unique: true
46+
3947
create_table :composite_primary_key_items, primary_key: [:item_id, :account_id], force: true do |t|
4048
t.integer :item_id, null: false
4149
t.integer :account_id, null: false

test/test_positioning.rb

+17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require_relative "models/list"
44
require_relative "models/item"
55
require_relative "models/new_item"
6+
require_relative "models/default_scope_item"
67
require_relative "models/composite_primary_key_item"
78
require_relative "models/category"
89
require_relative "models/categorised_item"
@@ -1760,4 +1761,20 @@ def test_heal_position_with_no_scope
17601761

17611762
assert_equal [1, 2, 3], [third_category.reload, second_category.reload, first_category.reload].map(&:position)
17621763
end
1764+
1765+
def test_heal_position_with_default_scope
1766+
first_list = List.create name: "First List"
1767+
1768+
first_item = first_list.default_scope_items.create name: "First Item"
1769+
second_item = first_list.default_scope_items.create name: "Second Item"
1770+
third_item = first_list.default_scope_items.create name: "Third Item"
1771+
1772+
first_item.update_columns position: 10
1773+
second_item.update_columns position: 15
1774+
third_item.update_columns position: 5
1775+
1776+
DefaultScopeItem.heal_position_column!
1777+
1778+
assert_equal [1, 2, 3], [third_item.reload, first_item.reload, second_item.reload].map(&:position)
1779+
end
17631780
end

0 commit comments

Comments
 (0)