Existe uma maneira de alterar em massa os 'nomes' dos usuários (nota: não nomes de usuário)

Temos algumas centenas de usuários em nosso fórum cujos nomes (não os nomes de usuário, nomes) foram acidentalmente definidos como seus endereços de e-mail devido à configuração do provedor externo de SSO (via WordPress) no momento da criação das contas.

Existe uma maneira relativamente simples de alterar em massa esses nomes de the_name@example.com para the_name (ou seja, truncar tudo a partir do ‘@’ em diante) sem precisar acessar manualmente cada perfil e alterá-los um por um?

Você pode fazer isso pelo console do Rails. É mais complicado do que pode ser explicado aqui, especialmente porque os endereços de e-mail não estão mais no registro do usuário. Se você tiver um orçamento, pode postar em Marketplace ou me contatar diretamente.

Ou, se você não se importa com o endereço de e-mail real…

Algo como

users = User.where('username like', '%@%')

Depois, você iteraria sobre os resultados e usaria gsub para remover tudo a partir do @ até o final. É o melhor que consigo fazer pelo meu celular.

Agradeço a resposta, @pfaffman. Posso escrever o SQL, mas trabalhar no console do Rails está um pouco fora da minha zona de conforto. Como posso acessar o console Python do Discourse :slightly_smiling_face:?

Seria legal — embora eu entenda que também possa ser perigoso — se houvesse uma ferramenta como o Explorador de Dados que também permitisse escrever uma consulta UPDATE.

Alguém sabe se existe uma maneira de conectar uma ferramenta SQL de terceiros (como o Sequel Pro ou equivalente) ao banco de dados em execução no Discourse auto-hospedado via Docker?

Sim, mas fazer isso no Rails torna muito mais difícil estragar seu banco de dados. Por exemplo, se você fizer isso com o Rails, saberá que não criou nomes de usuário ilegais (e, se alguma outra tabela precisar ser atualizada quando você modificar a que está mexendo, o Rails fará isso; o SQL não fará).

cd /var/discourse
./launcher enter app
rails c

Agora você está no Rails.

users=User.where("username like '%@%'")
users.each do |user|
  user.name.gsub!(/@(.*)/,"")
  puts "Novo nome: #{user.name}"
  # user.save
end

Acho que isso fará o que você quer. Se parecer que sim, você pode descomentar o user.save e tentar sua sorte.

Faça um backup primeiro, ok? (Ou, melhor ainda, em um servidor de staging.)

Uau, muito obrigado pelo código!

Não tenho um servidor de staging para esta instância do Discourse, mas posso fazer um backup e executar o código muito cedo amanhã de manhã, quando provavelmente não haverá muito (ou nenhum) tráfego, para que eu possa restaurar imediatamente se houver algum problema.

Muito obrigado, @pfaffman.

Você deve estar bastante seguro se os puts estiverem ok. Abraços!

Cortar no @ ainda deixa informações pessoais (endereço de e-mail) amplamente visíveis para a Grande Internet Malvada (já que a maioria das pessoas usa @gmail.com ou alguns outros grandes provedores). Provavelmente, seria melhor configurá-los com o mesmo valor do nome de usuário.

Obrigado @lionel-rowe, esse é um bom ponto. Os nomes de usuário já são esse mesmo valor, no entanto (o nome de usuário foi criado pegando tudo antes do ‘@’ do endereço de e-mail do usuário).

O horror.

Precisei fazer uma pequena alteração no código e adicionar um pequeno procedimento para que funcionasse. Aqui está o código modificado:

users=User.where("name like '%@%'")

Em seguida, o console do Rails começou a exibir os dados dos usuários com o “more”, então precisei pressionar q para sair. Depois:

users.each do |user|
  user.name.gsub!(/@(.*)/,"")
  puts "Novo nome: #{user.name}"
  # user.save
end

O console do Rails então mostrou a lista de novos nomes (corretos!) e me colocou de volta em um “more” dos usuários. q novamente.

Depois:

users.each do |user|
  user.name.gsub!(/@(.*)/,"")
  puts "Novo nome: #{user.name}"
  user.save
end

…e não há mais nomes de usuário com endereços de e-mail, e tudo está funcionando bem na interface do fórum.

Obrigado novamente, @pfaffman, pela sua ajuda generosa.