Defect #37166

Roles of a project member can be made empty

Added by Go MAEDA 30 days ago.

Status:NewStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:Project settings
Target version:-
Resolution: Affected version:5.0.0

Description

A project member must have one or more roles. If you attempt to add a project member without roles, you will see an error "Failed to save member(s): Role cannot be empty".

However, In Redmine 5.0.1, member roles can be emptied with the following procedure.

1. Add a new member to a project with any roles
2. After adding a role, click "Edit" for the member role
3. Clear the checkbox for each role and click "Save"

In Redmine 4.2, the above procedure will delete the member, but not in Redmine 5.0. This may be due to the difference in the behavior of Member#role_ids = [] (source:trunk/app/models/member.rb@21456#L105) between Redmine 4.2 (Rails 5.2) and Redmine 5.0 (Rails 6.1).

When setting an empty array to Member#role_ids, Redmine 4.2 destroys MemberRole and Member, but Redmine 5.0 only destroys MemberRole. Destroying only MemberRole makes a project member with empty roles.

Redmine 4.2:

irb(main):002:0> member.role_ids = []
  MemberRole Load (0.2ms)  SELECT "member_roles".* FROM "member_roles" WHERE "member_roles"."member_id" = ?  [["member_id", 17]]
   (0.6ms)  SELECT DISTINCT "roles"."id" FROM "roles" INNER JOIN "member_roles" ON "roles"."id" = "member_roles"."role_id" WHERE "member_roles"."member_id" = ?  [["member_id", 17]]
   (0.1ms)  begin transaction
  MemberRole Destroy (1.2ms)  DELETE FROM "member_roles" WHERE "member_roles"."id" = ?  [["id", 21]]
  Role Exists (0.1ms)  SELECT  1 AS one FROM "roles" INNER JOIN "member_roles" ON "roles"."id" = "member_roles"."role_id" WHERE "member_roles"."member_id" = ? LIMIT ?  [["member_id", 17], ["LIMIT", 1]]
  MemberRole Load (0.1ms)  SELECT "member_roles".* FROM "member_roles" WHERE "member_roles"."member_id" = ?  [["member_id", 17]]
  IssueCategory Update All (1.0ms)  UPDATE "issue_categories" SET assigned_to_id = NULL WHERE (project_id = 1 AND assigned_to_id = 8)
  Project Load (0.7ms)  SELECT  "projects".* FROM "projects" WHERE "projects"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  Member Destroy (0.3ms)  DELETE FROM "members" WHERE "members"."id" = ?  [["id", 17]]
  MemberRole Load (0.2ms)  SELECT "member_roles".* FROM "member_roles" WHERE "member_roles"."inherited_from" = ?  [["inherited_from", 21]]
   (2.1ms)  commit transaction
=> []

Redmine 5.0:

irb(main):011:0> member.role_ids = []
  MemberRole Load (0.2ms)  SELECT "member_roles".* FROM "member_roles" WHERE "member_roles"."member_id" = ?  [["member_id", 11]]
   (0.2ms)  SELECT DISTINCT "roles"."id" FROM "roles" INNER JOIN "member_roles" ON "roles"."id" = "member_roles"."role_id" WHERE "member_roles"."member_id" = ?  [["member_id", 11]]                                                     
  TRANSACTION (0.1ms)  begin transaction                                   
  MemberRole Destroy (1.3ms)  DELETE FROM "member_roles" WHERE "member_roles"."id" = ?  [["id", 35]]
  MemberRole Load (0.1ms)  SELECT "member_roles".* FROM "member_roles" WHERE "member_roles"."inherited_from" = ?  [["inherited_from", 35]]
  TRANSACTION (4.5ms)  commit transaction                                  
  MemberRole Load (0.2ms)  SELECT "member_roles".* FROM "member_roles" WHERE "member_roles"."member_id" = ?  [["member_id", 11]]
  Role Load (0.2ms)  SELECT DISTINCT "roles".* FROM "roles" INNER JOIN "member_roles" ON "roles"."id" = "member_roles"."role_id" WHERE "member_roles"."member_id" = ?  [["member_id", 11]]                                               
=> [] 

member_without_roles.png (69.6 KB) Go MAEDA, 2022-05-27 11:31

Also available in: Atom PDF