Alle Benutzer löschen, die nicht in einer bestimmten Gruppe sind

Im Rahmen einer Discourse-zu-Discourse-Migration/einer Zusammenführung versuche ich, alle Benutzer zu löschen, die nicht in einer bestimmten Gruppe sind.

Ich habe dies in der Rails-Konsole versucht:
User.joins(:group_users).where.not(group_users:{group_id:135}).destroy_all

Leider wurden dadurch alle Benutzer gelöscht, was ziemlich schmerzhaft war!

Ich habe einen umständlichen Weg gefunden, dies über die Benutzeroberfläche und etwas hässlichen Rails-Code zu erledigen, aber gibt es eine einfache Möglichkeit? Ich habe die Syntax wahrscheinlich nur falsch angewendet.

Hier ist, was ich versucht habe, nachdem ich schmerzhaft eine Mega-Gruppe der zu löschenden Benutzer (ca. 6000) über die GUI erstellt habe:

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

Außerdem, was ist der Unterschied zwischen der Verwendung von destroy und UserDestroyer? Sollte ich letzteren verwenden?

Ich beantworte meine eigene Frage und habe dabei ein paar Lehren gezogen.

  1. Ja, verwenden Sie UserDestroyer, sonst wird Ihre Datenbank mit verwaisten Datensätzen übersät sein.
  2. Sie müssen möglicherweise geschickt vorgehen, um Ihre unerwünschten Benutzer zu sammeln. Ich habe diese Data-Explorer-Abfrage verwendet, um eine Liste zu erhalten, die ich dann in einer Gruppe namens unwanted zusammengefasst habe.
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

So löschen Sie viele Benutzer:

Starten Sie die Discourse-App (./launcher enter app usw.) und führen Sie Folgendes aus:

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

Es ist nicht schnell. Für 6000 Benutzer hat es 2 Stunden gedauert.