diff --git a/app/models/project.rb b/app/models/project.rb index 295d3cb05..f58a14bae 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -393,6 +393,15 @@ class Project < ActiveRecord::Base end end + # Recalculates all lft and rgt values based on project names + # Unlike Project.rebuild!, these values are recalculated even if the tree "looks" valid + def self.rebuild_tree! + transaction do + update_all "lft = NULL, rgt = NULL" + rebuild!(false) + end + end + # Returns an array of the trackers used by the project and its active sub projects def rolled_up_trackers @rolled_up_trackers ||= diff --git a/test/unit/project_nested_set_test.rb b/test/unit/project_nested_set_test.rb index 3bd37609b..b038f30ac 100644 --- a/test/unit/project_nested_set_test.rb +++ b/test/unit/project_nested_set_test.rb @@ -54,6 +54,15 @@ class ProjectNestedSetTest < ActiveSupport::TestCase assert_valid_nested_set end + def test_rebuild_tree_should_build_valid_tree_even_with_valid_lft_rgt_values + Project.update_all "name = 'YY'", {:id => @a.id } + # lft and rgt values are still valid (Project.rebuild! would not update anything) + # but projects are not ordered properly (YY is in the first place) + + Project.rebuild_tree! + assert_valid_nested_set + end + def test_moving_a_child_to_a_different_parent_should_keep_valid_tree assert_no_difference 'Project.count' do Project.find_by_name('B1').set_parent!(Project.find_by_name('A2'))