В рамках миграции/объединения Discourse в Discourse я пытаюсь удалить всех пользователей, которые не входят в конкретную группу.
Я попробовал следующее в консоли Rails: User.joins(:group_users).where.not(group_users:{group_id:135}).destroy_all
К сожалению, это удалило всех пользователей, что стало довольно неприятным сюрпризом!
Я нашел громоздкий способ сделать это через интерфейс и с помощью неуклюжего кода на 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
Также, в чем разница между использованием destroy и UserDestroyer? Должен ли я использовать последний?
Отвечаю на свой собственный вопрос, извлекши несколько уроков.
Да, используйте UserDestroyer, иначе ваша база данных будет завалена сиротскими записями.
Вам, возможно, придется проявить изобретательность в том, как вы собираете нежелательных пользователей. Я использовал этот запрос в Data Explorer, чтобы получить их список, а затем массово добавил их в группу под названием 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 часа.