Mudança em Massa de Propriedade de Primeiros Posts por Tag – Revisão de Script e Sugestões

Olá,

Estou procurando alterar a propriedade de todas as postagens de abertura em tópicos de eventos marcados com “ethan” para que o proprietário mude de “system” para o usuário “Ethan_Hoom1”. Estou executando uma instância auto-hospedada e tenho acesso ao console do Rails.

Após revisar as recomendações em Administrative Bulk Operations e Change ownership of all posts by a specific user, preparei o seguinte script. Agradeceria quaisquer sugestões ou melhores práticas antes de executá-lo em produção:


# Encontra o objeto de tag com o nome "ethan"
tag = Tag.find_by(name: "ethan")

# Para imediatamente se a tag não for encontrada
raise "Tag not found" unless tag


# Encontra o usuário que se tornará o novo proprietário das postagens
# username_lower é mais seguro que username (insensível a maiúsculas e minúsculas)
new_owner = User.find_by(username_lower: "ethan_hoom1")

# Para imediatamente se o usuário de destino não for encontrado
raise "New owner user not found" unless new_owner


# Encontra a conta de usuário do sistema
# Retorna para Discourse.system_user caso a busca pelo registro falhe
system_user = User.find_by(username_lower: "system") || Discourse.system_user

# Para imediatamente se o usuário do sistema não puder ser encontrado
raise "System user not found" unless system_user


# Quando verdadeiro, o script apenas imprimirá o que MUDARIA
# e não modificará nada no banco de dados
DRY_RUN = true

# Limite de segurança opcional para a primeira execução (ex: 10 ou 50)
# Defina como nil para processar todas as postagens correspondentes
LIMIT = nil


# Constrói uma consulta ActiveRecord para as postagens que queremos modificar
scope = Post
  # Junta postagens → tópicos → topic_tags para que possamos filtrar por tag
  .joins(topic: :topic_tags)

  # Visa apenas a postagem de abertura em cada tópico
  .where(post_number: 1)

  # Visa apenas postagens atualmente pertencentes ao usuário do sistema
  .where(user_id: system_user.id)

  # Inclui apenas tópicos que têm a tag "ethan"
  .where(topic_tags: { tag_id: tag.id })

  # Exclui mensagens privadas e tópicos excluídos
  .where(topics: {
    archetype: Archetype.default,
    deleted_at: nil
  })


# Se LIMIT estiver definido, restringe quantas postagens são processadas
scope = scope.limit(LIMIT) if LIMIT


# Itera sobre as postagens correspondentes em lotes para evitar problemas de memória
scope.find_each(batch_size: 100) do |first_post|

  # Armazena o ID do tópico para saída de log
  topic_id = first_post.topic_id


  # Se o modo dry-run estiver ativado, não modifique nada
  if DRY_RUN
    puts "[DRY RUN] Would change owner for topic #{topic_id} (post #{first_post.id})"
    next
  end


  begin
    # Usa o serviço oficial de alteração de propriedade do Discourse
    PostOwnerChanger.new(
      # Altera a propriedade apenas da postagem de abertura
      post_ids: [first_post.id],

      # O tópico contendo a postagem
      topic_id: topic_id,

      # O usuário que se tornará o novo proprietário
      new_owner: new_owner,

      # O usuário que está realizando a ação (usuário do sistema)
      acting_user: system_user,

      # Não cria uma revisão de edição para esta alteração
      skip_revision: true
    ).change_owner!


    # Registra o sucesso no console
    puts "Changed owner for topic #{topic_id} (post #{first_post.id})"

  rescue => e
    # Se algo falhar, registra o erro, mas continua processando os outros
    puts "FAILED topic #{topic_id} (post #{first_post.id}): #{e.class}: #{e.message}"
  end
end

Perguntas:

  • Existem quaisquer ressalvas ou casos extremos que eu deva estar ciente com o PostOwnerChanger para este caso de uso?
  • É aconselhável atualizar também o campo topic.user como mostrado na linha opcional?
  • Você tem alguma recomendação para maior segurança ou melhorias de desempenho em relação a este processo em lote?

Obrigado pela sua ajuda e por toda a ótima documentação!

1 curtida