Bulk deleting / mass modifying users


Recently we’ve been migrating our bbpress forums to discourse at purism (a company that builds security focused laptops by trying to free the hardware from binary blobs) . I’ve already wrote a tutorial on how to import a bbpress backup and now I will focus on another problem we’ve encountered.

After importing the backup we’ve discovered a substantial amount of users who haven’t posted into the forums yet. This was due to the bbpress import script importing all wordpress users. We had to find a way to delete them, and we were sure as hell not going to do that one at a time!

##How to bulk delete users or mass modify them in a specific way?
In this tutorial I will show how to bulk delete users which have not posted yet.

WARNING: Please be very careful using this script and be sure to backup your files before.

First open a command line on your discourse server and then open the file delete_users.rb in your favorite editor. Paste the following contents inside.

require_relative '../config/environment'

pm = 0
User.find_each do |u|
  if u.post_count == 0 && u.topic_count == 0
    puts "Deleting user #{u.id}, #{u.name}, #{u.username}, #{u.email} ..."
    pm = pm +1
puts "Delete a total of #{pm} users"

This code loops through all existing users

User.find_each do |u|

Finds those who haven’t added a topic or post yet

if u.post_count == 0 && u.topic_count == 0

and deletes them


You can now copy the script inside your docker container app

$ docker cp delete_users.rb app:/var/www/discourse/script/

Enter the discourse container app

$ ./launcher enter app

And then execute the script

$ su discourse -c "bundle exec ruby script/delete_users.rb"

If you want to delete your users based on different information or if you want to only modify them I would start searching in the User class at app/models/user.rb in the discourse source code.

Default view only showing 2 poster avatars, unlike Discourse Meta
(Jonathon) #2

A potentially more efficient way would be to select the users and delete as one transaction:

User.joins(:user_stat).where("user_stats.post_count = 0 AND user_stats.topic_count = 0").destroy_all

See also: