From 4209293bc11f4e292704a97494e65be3e4874609 Mon Sep 17 00:00:00 2001 From: kumojima Date: Fri, 12 Sep 2025 18:10:37 +0900 Subject: optimize Project#remove_inherited_member_roles --- app/models/project.rb | 35 +++++++++++++------ test/unit/project_members_inheritance_test.rb | 31 ++++++++++++++++ 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index b3bf88c94..a90cc6258 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1023,6 +1023,31 @@ class Project < ApplicationRecord end end + def remove_inherited_member_roles(not_deleted_ids_at_parent=[]) + member_ids = membership_ids + member_roles = MemberRole.where(member_id: member_ids) + not_delete_ids = member_roles.where(inherited_from: nil).ids + not_delete_ids += member_roles.where(inherited_from: member_roles.ids + not_deleted_ids_at_parent).ids + delete_member_roles = member_roles.where.not(id: not_delete_ids).delete_all + + # MemberRole#remove_member_if_empty + delete_member_ids = Member.where(id: member_ids).left_outer_joins(:roles).where(roles: {id: nil}).ids + delete_members = Member.where(id: delete_member_ids) + delete_member_user_ids = delete_members.pluck(:user_id) + delete_members.delete_all + + # Member#set_issue_category_nil + IssueCategory.where(project_id: self.id, assigned_to_id: delete_member_user_ids).update_all("assigned_to_id = NULL") + + # Member#remove_from_project_default_assigned_to + if self.default_assigned_to_id && delete_member_user_ids.include?(self.default_assigned_to_id) + update_column(:default_assigned_to_id, nil) + end + + # MemberRole#remove_inherited_roles + children.where(inherit_members: true).map {|c| c.remove_inherited_member_roles(not_delete_ids) } + end + private def update_inherited_members @@ -1036,16 +1061,6 @@ class Project < ApplicationRecord end end - def remove_inherited_member_roles - member_roles = MemberRole.where(:member_id => membership_ids).to_a - member_role_ids = member_roles.map(&:id) - member_roles.each do |member_role| - if member_role.inherited_from && !member_role_ids.include?(member_role.inherited_from) - member_role.destroy - end - end - end - def add_inherited_member_roles if inherit_members? && parent parent.memberships.each do |parent_member| diff --git a/test/unit/project_members_inheritance_test.rb b/test/unit/project_members_inheritance_test.rb index a5f7b3d93..69a6184a5 100644 --- a/test/unit/project_members_inheritance_test.rb +++ b/test/unit/project_members_inheritance_test.rb @@ -119,6 +119,37 @@ class ProjectMembersInheritanceTest < ActiveSupport::TestCase assert_equal other_member.roles.sort, member.roles.sort end + def test_moving_a_subproject_as_root_should_clear_issue_category_assigned_to + Project.generate_with_parent!(@parent, :inherit_members => true) + project = Project.order('id desc').first + user = project.members.first.user + category = IssueCategory.create!(:project => project, :assigned_to => user, :name => 'foo') + + assert_difference 'Member.count', -1 do + project.set_parent!(nil) + project.reload + category.reload + + assert_equal 0, project.memberships.count + assert_nil category.assigned_to + end + end + + def test_moving_a_subproject_as_root_should_clear_default_assigned_to + Project.generate_with_parent!(@parent, :inherit_members => true) + project = Project.order('id desc').first + user = project.members.first.user + project.update!(:default_assigned_to => user) + + assert_difference 'Member.count', -1 do + project.set_parent!(nil) + project.reload + + assert_equal 0, project.memberships.count + assert_nil project.default_assigned_to + end + end + def test_inheritance_should_propagate_to_subprojects project = Project.generate_with_parent!(@parent, :inherit_members => false) subproject = Project.generate_with_parent!(project, :inherit_members => true) -- 2.34.1