Skip to content

Fix sibling reordering when node changes parent or scope#484

Draft
sampatbadhe wants to merge 3 commits intoClosureTree:masterfrom
sampatbadhe:fix/reorder-siblings-on-parent-and-scope-change
Draft

Fix sibling reordering when node changes parent or scope#484
sampatbadhe wants to merge 3 commits intoClosureTree:masterfrom
sampatbadhe:fix/reorder-siblings-on-parent-and-scope-change

Conversation

@sampatbadhe
Copy link

Summary

  • Fix siblings not being reordered when a root node becomes a child (via prepend_child, append_child, or add_sibling)
  • Fix siblings in previous scope not being reordered when a record moves to a different scope
  • Add cross-database tests for ordering behavior across PostgreSQL, SQLite, and MySQL

Problem

  1. When a root node was moved to become a child of another node, the remaining root nodes were left with gaps in their order_value sequence (e.g., 0, 2, 3 instead of 0, 1, 2).

  2. When a scoped record moved to a different scope (e.g., user_id changed from 1 to 2), siblings in the old scope were not reordered, leaving gaps.

Solution

  • Use previous scope values (via attribute_before_last_save) when reordering old parent's siblings
  • Trigger sibling reordering when scope changes, not just when parent changes
  • Add previous_scope_values_from_instance and scope_changed? helper methods

Changes

  • lib/closure_tree/hierarchy_maintenance.rb - Handle scope changes in _ct_after_save
  • lib/closure_tree/numeric_deterministic_ordering.rb - Use previous scope values in _ct_reorder_prior_siblings_if_parent_changed
  • lib/closure_tree/support.rb - Add previous_scope_values_from_instance and scope_changed? methods
  • test/closure_tree/order_value_cross_database_test.rb - New cross-database tests
  • test/closure_tree/scope_test.rb - Add scope change reordering tests

Fixes Root node siblings not reordered after prepend_child/add_sibling moves a root to child position

Updates prepend_child to reorder remaining root nodes when a root node becomes a child, ensuring order_values remain sequential. Adds tests to verify correct reordering for both prepend_child and append_child operations.
Ensure numeric ordering maintenance runs when the order column changes and add cross-database tests.

- hierarchy_maintenance.rb: run rebuild or sibling reordering from _ct_after_save when the order column changes; remove single-use skip-sort flag behavior.
- numeric_deterministic_ordering.rb: stop skipping sort-order maintenance in prepend/sibling operations so reordering happens correctly and avoid double reorders.
- tests: add order_value_cross_database_test to validate reorder behavior across PostgreSQL (Label), SQLite (MemoryTag) and MySQL (SecondaryTag); update label tests to persist order with update_columns.
- dummy/schema: enable numeric ordering by adding a sort_order column to test schemas and configuring MemoryTag and SecondaryTag with has_closure_tree order: :sort_order, numeric_order: true.
Detect and handle changes to scoped attributes during saves so siblings are reordered correctly when an object changes scope. _ct_after_save now checks for scope changes and triggers reordering of the prior and current siblings. _ct_reorder_prior_siblings_if_parent_changed was updated to consider scope changes (and early-return for new records), use the previous scope values, and only act when the parent or scope actually changed. Added support methods previous_scope_values_from_instance and scope_changed? to build previous-scope conditions and detect scope changes for Symbol or Array scope configurations. Tests were added to verify reordering behavior when moving items between scopes and with multiple scope attributes.
@_ct_skip_cycle_detection = true
end

def _ct_skip_sort_order_maintenance!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to deprecate a method before removal.

It can become no-op here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants