Bulk delete users that match an email pattern

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 Likes