What is the safest and most comprehensive way to delete a user from the system?
Not sure what “DELETE” would mean in terms of database but I am looking for the industry standard (what Facebook, LinkedIn, etc. would do when they delete their users)
I assume all user info, transaction history, messages, etc. will be gone.
I also assume that it will be the same as when the user clicks the button “DELETE ACCOUNT” under their settings.
Hi @phatza sorry for not clarifying.
I want the admin to be able to do it.
This is because we have many ghost users on the platform and we need to remove them manually.
Yes, there is no direct “button” to do that in the admin panel.
What I am wondering the ST team could help explain is how to do it in SQL or Rails command, that would be the cleanest and most professional way to do it.
Note that it does not remove existing messages and transactions, instead they render as being from “[deleted user]” , so other participants are not suprised that items from their Inbox disappear for unknown reason.
Syntax of your code is not valid, you can use following:
# by ID
target_user = Person.find("rZ...A")
# or target_user = Person.find_by_username("badusername")
ActiveRecord::Base.transaction do
Person.delete_user(target_user.id)
Listing.delete_by_author(target_user.id)
end
# another variant to delete from array of ids
bad_ids = ["q0...g","rZ...A"]
Person.where(id: bad_ids).each do |user_to_delete|
ActiveRecord::Base.transaction do
Person.delete_user(user_to_delete.id)
Listing.delete_by_author(user_to_delete.id)
end
end
But it only deletes the user from Person and Listing tables, right?
Wouldn’t a service like this be more complete?
class DeletePersonService
attr_reader :usernames
def initialize usernames
@usernames = usernames
end
def perform
ids = Person.where(username: usernames).pluck :id
ids.each do |id|
delete_user id
end
end
def delete_user id
person = Person.find_by(id: id)
if person.nil?
return false
else
# Delete personal information
person.update_attributes(
given_name: nil,
family_name: nil,
display_name: nil,
phone_number: nil,
description: nil,
email: nil,
facebook_id: nil,
username: "deleted_#{SecureRandom.hex(5)}",
current_sign_in_ip: nil,
last_sign_in_ip: nil,
# To ensure user can not log in anymore we have to:
#
# 1. Delete the password (Devise rejects login attempts if the password is empty)
# 2. Remove the emails (So that use can not reset the password)
encrypted_password: "",
deleted: true # Flag deleted
)
# Delete emails
person.emails.destroy_all
# Delete location
person.location&.destroy
# Delete avatar
person.image.destroy
person.image.clear
person.image = nil
person.save(validate: false)
# Delete follower relations, both way
person.follower_relationships.destroy_all
person.inverse_follower_relationships.destroy_all
# Delete memberships
person.community_membership.update_attributes(status: "deleted_user")
# Delte auth tokens
person.auth_tokens.destroy_all
end
end
end
target_users = Person.where.not(username: keep_usernames, deleted: true)
target_users.find_each do |target_user|
has_unfinished = TransactionService::Transaction.has_unfinished_transactions(target_user.id)
# Do not delete user who has unfinished transactions.
next if has_unfinished
# Start transaction
ActiveRecord::Base.transaction do
UserService::API::Users.delete_user(target_user.id)
MarketplaceService::Listing::Command.delete_listings(target_user.id)
PaypalService::API::Api.accounts.delete(community_id: target_user.community_id, person_id: target_user.id)
end
end
end
Steps to execute this rake:
ssh to target server (prod or stag server)
Go to your current folder
Edit the file tmp/keep_usernames.yml using vim or nano.