Bulk change of configuration via CLI in multiple user profiles/preferences

Hi Everybody,

I have multilingual forum so I enabled allow user locale and set locale from accept language header and it works great. I registered a test user and I noticed that the user web browser language gets saved into the new user profile (instead of (default)) which is perfect.

The only problem I have is that I migrated 800 users from phpBB and they all have (default) in the user profile. I know that large portion of them would like to use different language but I don’t want to change default English in the global configuration because I want English to be the default.

Could you please tell me would it be possible to enter Discourse (./launcher enter app) and loop through list of user names / IDs (anything) and change language in specified user profiles?

I was thinking to create a simple bash script like this:

while IFS= read -r username; do
  rails r "u = User.... $username"
done < list_of_usernames.txt

But I’m lacking Discourse knowledge to run a command to edit user preferences… Could you please me with this?

Thank you.

Rudy

1 Like

Yes, this can be done from the rails console. To get to the rails console, run ./launcher enter app, then enter rails c at the prompt to launch the rails console.

I’d be careful about looping through all users until you’re certain what’s going to happen. Here’s how I tested it for an individual user on my site:

First, get a list of the locales that are used by Discourse:

I18n.available_locales

That will print out a long list of symbols that Discourse uses for locales. For example :be, :bg, :bs_BA, :ca...

You can use these symbols to set the locale. For example, to update a user’s locale to French:

u = User.find(1)
u.update(locale: :fr)

If you want to loop through the users, you’ll need to figure out how to get arrays of users for each locale so that you can loop through them. If you have lists of usernames for each locale, that could be used to find the users. The simple way to do that from the console is to convert a list of usernames to an array. For example:

fr_users = ['bob', 'sally', 'john']

fr_users.each do |username|
    u = User.find_by(username: username)
    u.update(locale: :fr)
end

If you try this, proceed carefully. Make sure to create a backup of your site’s database before making the changes.

4 Likes

Thank you very much @simon - that code helped me a lot.

I have absolutely ZERO experience with Ruby but I do have experience with other languages so it didn’t take me too long to come with the following code:

all_users = User.find_each()

all_users.each do |user|
    if user.id > 70 and user.active == true and user.admin == false and user.trust_level == 1 and user.suspended_at == nil and user.moderator == false
        puts "MODIFY: #{user.id}: #{user.trust_level}: \"#{user.username}\""
        user.update(locale: :fr)
    else
        # skip this user
        puts "------: #{user.id}: #{user.trust_level}: \"#{user.username}\""
    end
end

I know nothing about Ruby so there is probably a clever way how to do it. But this works for me :wink: . Thank you.

5 Likes

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