Skip to content

Commit

Permalink
Merge pull request #27 from LukasSkywalker/main
Browse files Browse the repository at this point in the history
Fix healer when model uses an ordering default scope
  • Loading branch information
brendon authored Dec 3, 2024
2 parents 0252882 + b43d1cc commit b29b9ef
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## [Unreleased]

- Fix healing a list with a default scope `:order` and/or `:select`. Thanks @LukasSkywalker!

## [0.4.4] - 2024-11-20

- Add `funding_uri` to gemspec.
Expand Down
4 changes: 2 additions & 2 deletions lib/positioning/healer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def initialize(model, column, order)

def heal
if scope_columns.present?
@model.select(*scope_columns).distinct.each do |scope_record|
@model.unscope(:order).reselect(*scope_columns).distinct.each do |scope_record|
@model.transaction do
if scope_associations.present?
scope_associations.each do |scope_association|
Expand Down Expand Up @@ -40,7 +40,7 @@ def scope_associations
end

def sequence(scope)
scope.reorder(@order).each.with_index(1) do |record, index|
scope.unscope(:select).reorder(@order).each.with_index(1) do |record, index|
record.update_columns @column => index
end
end
Expand Down
7 changes: 7 additions & 0 deletions test/models/default_scope_item.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class DefaultScopeItem < ActiveRecord::Base
belongs_to :list

positioned on: :list

default_scope -> { select(:name, :position).order(:position) }
end
1 change: 1 addition & 0 deletions test/models/list.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class List < ActiveRecord::Base
has_many :items, -> { order(:position) }, dependent: :destroy
has_many :new_items, -> { order(:position) }, dependent: :destroy
has_many :default_scope_items, -> { order(:position) }, dependent: :destroy
has_many :composite_primary_key_items, -> { order(:position) }, dependent: :destroy
has_many :authors, -> { order(:position) }, dependent: :destroy
end
8 changes: 8 additions & 0 deletions test/support/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@
t.references :list, null: false
end

create_table :default_scope_items, force: true do |t|
t.string :name
t.integer :position, null: false
t.references :list, null: false
end

add_index :default_scope_items, [:list_id, :position], unique: true

create_table :composite_primary_key_items, primary_key: [:item_id, :account_id], force: true do |t|
t.integer :item_id, null: false
t.integer :account_id, null: false
Expand Down
17 changes: 17 additions & 0 deletions test/test_positioning.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_relative "models/list"
require_relative "models/item"
require_relative "models/new_item"
require_relative "models/default_scope_item"
require_relative "models/composite_primary_key_item"
require_relative "models/category"
require_relative "models/categorised_item"
Expand Down Expand Up @@ -1760,4 +1761,20 @@ def test_heal_position_with_no_scope

assert_equal [1, 2, 3], [third_category.reload, second_category.reload, first_category.reload].map(&:position)
end

def test_heal_position_with_default_scope
first_list = List.create name: "First List"

first_item = first_list.default_scope_items.create name: "First Item"
second_item = first_list.default_scope_items.create name: "Second Item"
third_item = first_list.default_scope_items.create name: "Third Item"

first_item.update_columns position: 10
second_item.update_columns position: 15
third_item.update_columns position: 5

DefaultScopeItem.heal_position_column!

assert_equal [1, 2, 3], [third_item.reload, first_item.reload, second_item.reload].map(&:position)
end
end

0 comments on commit b29b9ef

Please sign in to comment.