删除不在特定组中的所有用户

作为 Discourse 到 Discourse 迁移/合并的一部分,我试图删除所有不在特定组中的用户。

我在 Rails 控制台中尝试了以下代码:
User.joins(:group_users).where.not(group_users:{group_id:135}).destroy_all

不幸的是,这删除了所有用户,这真是让人头疼!

我发现了一种通过 UI 配合一些难看的 Rails 代码来实现的繁琐方法,但有没有更简单的方法?我可能只是把语法搞错了。

这是我尝试过的内容,在通过 GUI 痛苦地创建了一个包含所有待删除用户(约 6000 人)的巨型组之后:

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

另外,使用 destroyUserDestroyer 有什么区别?我是否应该使用后者?

回答我自己的问题,吸取了一些教训。

  1. 是的,请使用 UserDestroyer,否则您的数据库将充斥着孤立的记录。
  2. 您可能需要巧妙地收集不需要的用户。我使用了以下数据探索器查询来获取用户列表,然后将它们批量添加到一个名为 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

如何销毁大量用户:

进入 Discourse 应用(例如执行 ./launcher enter app 等命令),然后运行以下命令:

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

这并不快。处理 6000 个用户花费了 2 个小时。

1 个赞