Merge pull request #8742 from okriuchykhin/ok_SCI_12187_v2

Fix initial user assignments creation [SCI-12187]
This commit is contained in:
Alex Kriuchykhin 2025-08-05 13:08:49 +02:00 committed by GitHub
commit abcc1bfb44
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 44 deletions

View file

@ -24,7 +24,7 @@ module Assignable
class_name: 'TeamAssignment',
inverse_of: :assignable
after_create :create_users_assignments
after_create :create_user_assignments!, unless: -> { skip_user_assignments }
def users
direct_user_ids = user_assignments.select(:user_id)
@ -53,12 +53,11 @@ module Assignable
false
end
def role_for_user(user, team)
user_assignments.find_by(user: user, team: team)&.user_role ||
user_group_assignments.joins(user_group: :user_group_memberships)
.where(team: team, user_groups: { user_group_memberships: { user_id: user.id } })
.last&.user_role ||
team_assignments.find_by(team: team)&.user_role
def reset_all_users_assignments!(assigned_by)
user_assignments.destroy_all
user_group_assignments.destroy_all
team_assignments.destroy_all
create_user_assignments!(assigned_by)
end
def manually_assigned_users
@ -114,23 +113,31 @@ module Assignable
# Will be called when an assignment is changed (save/destroy) for the assignable model.
end
def create_users_assignments
return if skip_user_assignments
def create_user_assignments!(user = created_by)
# First create initial assignments for the object's creator
if top_level_assignable?
user_assignments.create!(user: user, assigned: :manually, user_role: UserRole.find_predefined_owner_role)
else
parent_assignment = permission_parent.user_assignments.find_by(user: user, team: team)
if parent_assignment.present?
user_assignments.create!(user: user, user_role: parent_assignment.user_role)
else
parent_group_assignments = permission_parent.user_group_assignments
.joins(user_group: :user_group_memberships)
.where(team: team, user_groups: { user_group_memberships: { user_id: user.id } })
if parent_group_assignments.present?
parent_group_assignments.each do |parent_group_assignment|
user_group_assignments.create!(user_group: parent_group_assignment.user_group, user_role: parent_group_assignment.user_role)
end
else
parent_team_assignment = permission_parent.team_assignments.find_by(team: team)
team_assignments.create!(team: team, user_role: parent_team_assignment.user_role) if parent_team_assignment.present?
end
end
end
role = if top_level_assignable?
UserRole.find_predefined_owner_role
else
permission_parent.role_for_user(created_by, team)
end
UserAssignment.create!(
user: created_by,
assignable: self,
assigned: top_level_assignable? ? :manually : :automatically,
user_role: role
)
UserAssignments::GenerateUserAssignmentsJob.perform_later(self, created_by.id)
# Generate assignments for the rest of users in the background
UserAssignments::GenerateUserAssignmentsJob.perform_later(self, user.id)
end
end
end

View file

@ -348,8 +348,7 @@ class Experiment < ApplicationRecord
next unless my_module.save
# regenerate user assignments
my_module.user_assignments.destroy_all
UserAssignments::GenerateUserAssignmentsJob.perform_later(my_module, current_user.id)
my_module.reset_all_users_assignments!(current_user)
Activities::CreateActivityService.call(activity_type: :move_task,
owner: current_user,
@ -405,8 +404,7 @@ class Experiment < ApplicationRecord
m.save!
# regenerate user assignments
m.user_assignments.destroy_all
UserAssignments::GenerateUserAssignmentsJob.new(m, current_user.id).perform_now
m.reset_all_users_assignments!(current_user)
# Add activity
Activities::CreateActivityService.call(

View file

@ -17,7 +17,7 @@ class Protocol < ApplicationRecord
include PermissionCheckableModel
include TinyMceImages
skip_callback :create, :after, :create_users_assignments, if: -> { in_module? }
before_create -> { self.skip_user_assignments = true }, if: -> { in_module? }
enum visibility: { hidden: 0, visible: 1 }
enum protocol_type: {

View file

@ -25,14 +25,14 @@ module Experiments
ActiveRecord::Base.transaction do
@exp.project = @project
sync_user_assignments(@exp)
@exp.reset_all_users_assignments!(@user)
@exp.my_modules.each do |my_module|
unless can_move_my_module?(@user, my_module)
@errors[:main] = I18n.t('move_to_project_service.my_modules_permission_error')
raise
end
sync_user_assignments(my_module)
my_module.reset_all_users_assignments!(@user)
clean_up_user_my_modules(my_module)
move_tags!(my_module)
end
@ -107,20 +107,6 @@ module Experiments
end
end
def sync_user_assignments(object)
# remove user assignments where the user are not present on the project
object.user_assignments.destroy_all
UserAssignment.create!(
user: @user,
assignable: object,
assigned: :automatically,
user_role: @project.user_assignments.find_by(user: @user).user_role
)
UserAssignments::GenerateUserAssignmentsJob.perform_later(object, @user.id)
end
def clean_up_user_my_modules(my_module)
my_module.user_my_modules.where.not(user_id: @project.users.select(:id)).destroy_all
end