diff options
author | Timothy Andrew <mail@timothyandrew.net> | 2017-04-05 12:50:53 +0530 |
---|---|---|
committer | Timothy Andrew <mail@timothyandrew.net> | 2017-04-06 18:58:57 +0530 |
commit | 72580f07af5a2c1e4df6bbc339ad804b5f5bb9ed (patch) | |
tree | a80a44687563e69aab8636c03c62e7d5e9b95230 /app/services | |
parent | fa65b65b0f5e7095e2ec7c4ca0c269a4fe4baab1 (diff) | |
download | gitlab-ce-72580f07af5a2c1e4df6bbc339ad804b5f5bb9ed.tar.gz |
Move a user's merge requests to the ghost user.
1. When the user is deleted.
2. Refactor out code relating to "migrating records to the ghost user" into a
`MigrateToGhostUser` concern, which is tested using a shared example.
Diffstat (limited to 'app/services')
-rw-r--r-- | app/services/concerns/users/migrate_to_ghost_user.rb | 38 | ||||
-rw-r--r-- | app/services/users/destroy_service.rb | 21 |
2 files changed, 41 insertions, 18 deletions
diff --git a/app/services/concerns/users/migrate_to_ghost_user.rb b/app/services/concerns/users/migrate_to_ghost_user.rb new file mode 100644 index 00000000000..ecbbf3026a0 --- /dev/null +++ b/app/services/concerns/users/migrate_to_ghost_user.rb @@ -0,0 +1,38 @@ +# When a user is destroyed, some of their associated records are +# moved to a "Ghost User", to prevent these associated records from +# being destroyed. +# +# For example, all the issues/MRs a user has created are _not_ destroyed +# when the user is destroyed. +module Users::MigrateToGhostUser + extend ActiveSupport::Concern + + attr_reader :ghost_user + + def move_associated_records_to_ghost_user(user) + # Block the user before moving records to prevent a data race. + # For example, if the user creates an issue after `move_issues_to_ghost_user` + # runs and before the user is destroyed, the destroy will fail with + # an exception. + user.block + + user.transaction do + @ghost_user = User.ghost + + move_issues_to_ghost_user(user) + move_merge_requests_to_ghost_user(user) + end + + user.reload + end + + private + + def move_issues_to_ghost_user(user) + user.issues.update_all(author_id: ghost_user.id) + end + + def move_merge_requests_to_ghost_user(user) + user.merge_requests.update_all(author_id: ghost_user.id) + end +end diff --git a/app/services/users/destroy_service.rb b/app/services/users/destroy_service.rb index a3b32a71a64..e6608e316dc 100644 --- a/app/services/users/destroy_service.rb +++ b/app/services/users/destroy_service.rb @@ -1,5 +1,7 @@ module Users class DestroyService + include MigrateToGhostUser + attr_accessor :current_user def initialize(current_user) @@ -26,7 +28,7 @@ module Users ::Projects::DestroyService.new(project, current_user, skip_repo: true).execute end - move_issues_to_ghost_user(user) + move_associated_records_to_ghost_user(user) # Destroy the namespace after destroying the user since certain methods may depend on the namespace existing namespace = user.namespace @@ -35,22 +37,5 @@ module Users user_data end - - private - - def move_issues_to_ghost_user(user) - # Block the user before moving issues to prevent a data race. - # If the user creates an issue after `move_issues_to_ghost_user` - # runs and before the user is destroyed, the destroy will fail with - # an exception. We block the user so that issues can't be created - # after `move_issues_to_ghost_user` runs and before the destroy happens. - user.block - - ghost_user = User.ghost - - user.issues.update_all(author_id: ghost_user.id) - - user.reload - end end end |