Bulk delete users that match an email pattern

I would like to bulk delete users that match an email pattern such as :

  • *.xyz
  • *.fun
  • etc…

I tried this as of now : User.find(UserEmail.where("email like '%.fun'").pluck(:user_id)).count. But I can’t use the destroy_all function after a .where()

Could you please help ?
Thanks a lot.

إعجابَين (2)

I would like to do the same, in addition to deleting all those users’ posts/topics too.

User.joins(:user_emails)
  .where('lower(user_emails.email) LIKE ?', '%domain.com')

In particular, the percentage sign (%) is a wildard that represents zero or more of any character. So %domain.com means emails ending with domain.com.

Rather than User#destroy, it’s best to use the UserDestroyer:

UserDestroyer.new(Discourse.system_user)
  .destroy(user, delete_posts: true)

This will have the system user delete the user and all of their posts.

To sum it up:

User.joins(:user_emails)
  .where('lower(user_emails.email) LIKE ?', '%domain.com')
  .find_each do |user|
    UserDestroyer.new(Discourse.system_user).destroy(user, delete_posts: true)
  end

Be ware that this is irreversable. You may want to verify the users selected by the query before actually deleting them. Also I am unsure of the performance implications if you’re deleting a great number of users and/or if they have a large number of posts.

On another note, not sure if Anonymizing Users in Discourse is an alternative for you?

7 إعجابات

Hi @xrav3nz ! This reply is awesome ! :open_mouth:
This is exactly what I need, I will try it right now, before I will confirm the amount with a basic count() of course as you suggested.

One remark, shouldn’t it be delete_post: true instead of false ?

My use case is very simple, I imported an old phpBB (thanks to @gerhard) and it has work perfectly, but this old forum what totally poluted by fake accounts… They did not post any message. All email addresses looks like .fun or .xyz.

إعجابَين (2)

Yes you’re right! Typo on my end!

إعجابَين (2)

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.