From 695f71713f36cdeb9eb1edfe5838ae7f39e19790 Mon Sep 17 00:00:00 2001 From: Sampat Badhe Date: Tue, 24 Feb 2026 09:14:03 +0530 Subject: [PATCH] Handle non-numeric order in _ct_after_save Only run reorder/scope-change logic when the order column is numeric. The _ct_after_save flow was restructured to guard calls to _ct.scope_changed? and sibling reordering with _ct.order_is_numeric?, preventing errors when models use a non-numeric order column. --- lib/closure_tree/hierarchy_maintenance.rb | 16 ++++++++-------- test/closure_tree/hierarchy_maintenance_test.rb | 8 ++++++++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/closure_tree/hierarchy_maintenance.rb b/lib/closure_tree/hierarchy_maintenance.rb index ffb376bb..3103dc06 100644 --- a/lib/closure_tree/hierarchy_maintenance.rb +++ b/lib/closure_tree/hierarchy_maintenance.rb @@ -41,16 +41,16 @@ def _ct_before_save end def _ct_after_save - scope_changed = _ct.order_is_numeric? && _ct.scope_changed?(self) - if saved_changes[_ct.parent_column_name] || @was_new_record rebuild! - elsif scope_changed - # Scope changed without parent change - reorder old scope's siblings - _ct_reorder_prior_siblings_if_parent_changed - _ct_reorder_siblings - elsif _ct.order_option? && saved_changes[_ct.order_column_sym] - _ct_reorder_siblings(saved_changes[_ct.order_column_sym].min) + elsif _ct.order_is_numeric? + if _ct.scope_changed?(self) + # Scope changed without parent change - reorder old scope's siblings + _ct_reorder_prior_siblings_if_parent_changed + _ct_reorder_siblings + elsif saved_changes[_ct.order_column_sym] + _ct_reorder_siblings(saved_changes[_ct.order_column_sym].min) + end end if saved_changes[_ct.parent_column_name] && !@was_new_record # Resetting the ancestral collections addresses diff --git a/test/closure_tree/hierarchy_maintenance_test.rb b/test/closure_tree/hierarchy_maintenance_test.rb index 75dc0a3d..6225ee55 100644 --- a/test/closure_tree/hierarchy_maintenance_test.rb +++ b/test/closure_tree/hierarchy_maintenance_test.rb @@ -16,6 +16,14 @@ end end + describe '#_ct_after_save' do + it 'does not raise when updating a node with non-numeric order column' do + tag = Tag.create!(name: 'Alpha') + tag.update!(name: 'Beta') + assert_equal 'Beta', tag.reload.name + end + end + describe '.cleanup!' do before do @parent = Metal.create(value: 'parent metal')