Dans le cadre d’une migration ou d’une fusion de Discourse vers Discourse, je tente de supprimer tous les utilisateurs qui ne font pas partie d’un groupe spécifique.
J’ai essayé ceci dans la console Rails : User.joins(:group_users).where.not(group_users:{group_id:135}).destroy_all
Malheureusement, cela a supprimé tous les utilisateurs, ce qui a été assez pénible !
J’ai trouvé une méthode lourde pour le faire via l’interface utilisateur et un code Rails peu élégant, mais existe-t-il un moyen plus simple ? J’ai probablement simplement mal syntaxé la commande.
Voici ce que j’ai essayé, après avoir créé péniblement un méga-groupe de ceux à supprimer (environ 6000) via l’interface graphique :
rails c
target_group = Group.find_by_name("nz-not")
users = User.joins(:group_users).where(group_users:{group_id: target_group.id})
users.each do |u|
u.destroy
end
exit
De plus, quelle est la différence entre l’utilisation de destroy et UserDestroyer ? Devrais-je utiliser ce dernier ?
Je réponds à ma propre question, ayant tiré quelques leçons.
Oui, utilisez UserDestroyer, sinon votre base de données sera remplie d’enregistrements orphelins.
Vous devrez peut-être être astucieux pour rassembler les utilisateurs indésirables. J’ai utilisé cette requête Data Explorer pour obtenir une liste, que j’ai ensuite ajoutée en masse à un groupe nommé unwanted :
WITH included_users AS (
SELECT
gu.user_id
FROM group_users gu
JOIN groups g
ON g.id = gu.group_id
WHERE g.name = :included_group
),
excluded_users AS (
SELECT
gu.user_id
FROM group_users gu
JOIN groups g
ON g.id = gu.group_id
WHERE g.name = :excluded_group
)
SELECT
u.id AS user_id, u.username
FROM users as u
WHERE u.id in (SELECT user_id FROM included_users)
AND u.id NOT IN (SELECT user_id FROM excluded_users)
GROUP by u.id
Comment détruire un grand nombre d’utilisateurs :
Accédez à l’application Discourse (./launcher enter app, etc.) et exécutez les commandes suivantes :
rails c
target_group = Group.find_by_name("unwanted")
users = User.joins(:group_users).where(group_users:{group_id: target_group.id})
users.each do |u|
u.admin = false
u.moderator = false
u.save
UserDestroyer.new(Discourse.system_user).destroy(u, delete_posts: true)
end
Exit
Ce n’est pas rapide. Pour 6000 utilisateurs, cela a pris 2 heures.