Project

General

Profile

Defect #11508 » AwesomeNestedSetOrderUpdatePatch.patch

William Roush, 2012-08-05 03:21

View differences:

app/models/project.rb Thu Aug 02 17:37:03 2012 +0000 → app/models/project.rb Sat Aug 04 21:18:46 2012 -0400
58 58
                          :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}",
59 59
                          :association_foreign_key => 'custom_field_id'
60 60

  
61
  acts_as_nested_set :order => 'name', :dependent => :destroy
61
  acts_as_nested_set :order => 'name', :compare_method => lambda { |a,b| a.to_s.downcase > b.to_s.downcase }, :dependent => :destroy
62 62
  acts_as_attachable :view_permission => :view_files,
63 63
                     :delete_permission => :manage_files
64 64

  
......
367 367
    end
368 368
    set_parent!(p)
369 369
  end
370
  
371
  def nested_set_rebuild(parent_node)
372
    update_node_order(parent_node)
373
    Issue.update_versions_from_hierarchy_change(self)
374
  end
370 375

  
371 376
  # Sets the parent of the project
372 377
  # Argument can be either a Project, a String, a Fixnum or nil
......
383 388
      # Nothing to do
384 389
      true
385 390
    elsif p.nil? || (p.active? && move_possible?(p))
386
      # Insert the project so that target's children or root projects stay alphabetically sorted
387
      sibs = (p.nil? ? self.class.roots : p.children)
388
      to_be_inserted_before = sibs.detect {|c| c.name.to_s.downcase > name.to_s.downcase }
389
      if to_be_inserted_before
390
        move_to_left_of(to_be_inserted_before)
391
      elsif p.nil?
392
        if sibs.empty?
393
          # move_to_root adds the project in first (ie. left) position
394
          move_to_root
395
        else
396
          move_to_right_of(sibs.last) unless self == sibs.last
397
        end
398
      else
399
        # move_to_child_of adds the project in last (ie.right) position
400
        move_to_child_of(p)
401
      end
402
      Issue.update_versions_from_hierarchy_change(self)
391
      nested_set_rebuild(p)
403 392
      true
404 393
    else
405 394
      # Can not move to the given target
......
407 396
    end
408 397
  end
409 398

  
399
  def save
400
    changed = name_changed?
401
    ret_val = super
402
    if changed
403
      nested_set_rebuild(parent)
404
    end
405
    ret_val
406
  end
407

  
410 408
  # Returns an array of the trackers used by the project and its active sub projects
411 409
  def rolled_up_trackers
412 410
    @rolled_up_trackers ||=
lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb Thu Aug 02 17:37:03 2012 +0000 → lib/plugins/awesome_nested_set/lib/awesome_nested_set/awesome_nested_set.rb Sat Aug 04 21:18:46 2012 -0400
380 380
          end.join("\n")
381 381
        end
382 382

  
383
        def update_node_order(parent_node)
384
          order = acts_as_nested_set_options[:order]
385
          method = acts_as_nested_set_options[:compare_method]
386
          sibs = (parent_node.nil? ? self.class.roots : parent_node.children)
387
          to_be_inserted_before = sibs.detect {|c| 
388
            a = c.read_attribute("#{order}")
389
            b = read_attribute("#{order}")
390
            if method.nil?
391
              a > b
392
            else
393
              method.call(a,b)
394
            end
395
          }
396
          if to_be_inserted_before
397
            move_to_left_of(to_be_inserted_before)
398
          elsif parent_node.nil?
399
            if sibs.empty?
400
              # move_to_root adds the node in first (ie. left) position
401
              move_to_root
402
            else
403
              move_to_right_of(sibs.last) unless self == sibs.last
404
            end
405
          else
406
            # move_to_child_of adds the node in last (ie.right) position
407
            move_to_child_of(parent_node)
408
          end
409
        end
410

  
383 411
      protected
384 412

  
385 413
        def without_self(scope)
test/unit/project_test.rb Thu Aug 02 17:37:03 2012 +0000 → test/unit/project_test.rb Sat Aug 04 21:18:46 2012 -0400
775 775
    assert !project.activities.include?(system_activity), "System activity found when the project has an inactive override"
776 776
  end
777 777

  
778
  # See issue #11508, updating a project does not reorder sibilings alphabetically.
779
  def test_rebuild_should_sort_children_alphabetically_on_update
780
    ProjectCustomField.delete_all
781

  
782
    # Create 4 projects under a parent project.
783
    parent = Project.create!(:name => 'Parent', :identifier => 'parent')
784
    Project.create!(:name => 'Project C', :identifier => 'project-c').move_to_child_of(parent)
785
    Project.create!(:name => 'Project B', :identifier => 'project-b').move_to_child_of(parent)
786
    Project.create!(:name => 'Project D', :identifier => 'project-d').move_to_child_of(parent)
787
    renamed_project = Project.create!(:name => 'Project A', :identifier => 'project-a').move_to_child_of(parent)
788

  
789
    # Rebuild them all.
790
    Project.update_all("lft = NULL, rgt = NULL")
791
    Project.rebuild!
792

  
793
    # Confirm that everything is as expected.
794
    all_projects = Project.find(:all, :order => 'lft')
795
    assert_equal 'Project D', all_projects.last.name
796

  
797
    # Load and modify project-a, which causes defect #11508
798
    project = Project.find_by_id(renamed_project.id)
799
    project.name = 'Project E'
800
    assert_equal true, project.save
801

  
802
    # Reload all projects and verify that "Project E" is last.
803
    all_projects = Project.find(:all, :order => 'lft')
804
    assert_equal 'Project E', all_projects.last.name
805
  end
806

  
778 807
  def test_close_completed_versions
779 808
    Version.update_all("status = 'open'")
780 809
    project = Project.find(1)
(5-5/5)