Class: Organizations::Users::TransferService
- Inherits:
-
Object
- Object
- Organizations::Users::TransferService
- Includes:
- Gitlab::Utils::StrongMemoize, Concerns::OrganizationUpdater
- Defined in:
- app/services/organizations/users/transfer_service.rb
Constant Summary collapse
- BATCH_SIZE =
50
Constants included from Concerns::OrganizationUpdater
Concerns::OrganizationUpdater::ORGANIZATION_ID_UPDATE_BATCH_SIZE
Instance Method Summary collapse
- #can_transfer_users? ⇒ Boolean
- #execute ⇒ Object
-
#initialize(users:, new_organization:) ⇒ TransferService
constructor
A new instance of TransferService.
-
#prepare_bots ⇒ Object
Pre-create bot users before the transaction to avoid exclusive lease errors This is called by the group transfer service before starting the transaction.
- #transfer_error ⇒ Object
-
#users_belong_to_single_organization? ⇒ Boolean
rubocop:disable CodeReuse/ActiveRecord – Query specific to this service rubocop:disable Database/AvoidUsingPluckWithoutLimit – Using batches of 50.
Methods included from Concerns::OrganizationUpdater
Constructor Details
#initialize(users:, new_organization:) ⇒ TransferService
Returns a new instance of TransferService.
11 12 13 14 |
# File 'app/services/organizations/users/transfer_service.rb', line 11 def initialize(users:, new_organization:) @users = users @new_organization = new_organization end |
Instance Method Details
#can_transfer_users? ⇒ Boolean
47 48 49 50 51 52 |
# File 'app/services/organizations/users/transfer_service.rb', line 47 def can_transfer_users? return false unless users_belong_to_single_organization? return false unless old_organization.present? true end |
#execute ⇒ Object
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'app/services/organizations/users/transfer_service.rb', line 16 def execute return ServiceResponse.error(message: transfer_error) unless can_transfer_users? # Only create a transaction if we're not already in one # This allows the related organization group transfer # service to manage the outer transaction in_outer_transaction = User.connection.transaction_open? if in_outer_transaction perform_transfer else User.transaction do perform_transfer end end ServiceResponse.success rescue StandardError => e # When in outer transaction: re-raise to propagate and trigger rollback # When managing own transaction: return error (transaction already rolled back) raise e if in_outer_transaction ServiceResponse.error(message: e.) end |
#prepare_bots ⇒ Object
Pre-create bot users before the transaction to avoid exclusive lease errors This is called by the group transfer service before starting the transaction
43 44 45 |
# File 'app/services/organizations/users/transfer_service.rb', line 43 def prepare_bots new_organization_bots end |
#transfer_error ⇒ Object
54 55 56 57 58 |
# File 'app/services/organizations/users/transfer_service.rb', line 54 def transfer_error return organization_not_found_error unless old_organization.present? users_different_organizations_error unless users_belong_to_single_organization? end |
#users_belong_to_single_organization? ⇒ Boolean
rubocop:disable CodeReuse/ActiveRecord – Query specific to this service rubocop:disable Database/AvoidUsingPluckWithoutLimit – Using batches of 50
62 63 64 65 66 67 |
# File 'app/services/organizations/users/transfer_service.rb', line 62 def users_belong_to_single_organization? organization_ids = users.distinct.pluck(:organization_id).compact # All users must belong to exactly one organization organization_ids.size == 1 end |