Impossibile sospendere/disattivare utenti in blocco nella console Rails su Discourse 3.5.0.beta5-dev

Ciao a tutti,

Sto affrontando un problema persistente nel tentativo di sospendere/disattivare in blocco gli utenti sulla mia istanza Discourse (versione 3.5.0.beta5-dev) tramite la console Rails. Sto cercando di escludere il mio account amministratore (hoangthai, ID utente 100) e di sospendere permanentemente tutti gli altri utenti attivi non amministratori/non moderatori con un motivo personalizzato “Chưa gia hạn tài khoản” (Rinnovo dell’account in sospeso).

Ho provato diversi approcci basati su comandi comuni della console Discourse e suggerimenti di debug, ma gli account rimangono active: true anche se suspended_at e suspended_till potrebbero essere impostati.

Ecco un’analisi di ciò che ho tentato e degli errori/risultati:

Il mio obiettivo: Sospendere permanentemente tutti gli utenti (tranne hoangthai, ID 100) con il motivo “Chưa gia hạn tài khoản” (Rinnovo dell’account in sospeso).

Tentativi e problemi:

  1. Tentativo iniziale (Impostazione diretta di suspend_reason, suspended_at, suspended_till):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? && !user.admin? && !user.moderator?
        user.suspend_reason = "Tài khoản tạm khóa do nghỉ phép dài hạn." # Primo tentativo di motivo
        user.suspended_at = Time.current
        user.suspended_till = Time.current + 100.years
        user.save!
        puts "Khóa tài khoản: #{user.username}"
      end
    end
    
    • Risultato: NoMethodError: undefined method 'suspend_reason=' for an instance of User (suggerito suspended_at=). Questo indicava che suspend_reason non era l’attributo corretto.
  2. Secondo tentativo (Utilizzo di UserSuspension.suspend_user come suggerito per le versioni più recenti):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? && !user.admin? && !user.moderator?
        UserSuspension.suspend_user(
            user,
            Time.current + 100.years,
            nil, # suspend_reason_id
            "Tài khoản tạm khóa: Nghỉ phép dài hạn.", # custom_suspend_reason
            Discourse.system_user
        )
        puts "Đã khóa tài khoản: #{user.username}"
      end
    end
    
    • Risultato: NameError: uninitialized constant UserSuspension (suggerito UserSuspender). Questo indicava che il nome della classe era errato.
  3. Terzo tentativo (Nome della classe corretto in UserSuspender):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? && !user.admin? && !user.moderator?
        UserSuspender.suspend_user( # Still trying suspend_user
            user,
            Time.current + 100.years,
            nil,
            "Tài khoản tạm khóa: Nghỉ phép dài hạn.",
            Discourse.system_user
        )
        puts "Đã khóa tài khoản: #{user.username}"
      end
    end
    
    • Risultato: NoMethodError: undefined method 'suspend_user' for class UserSuspender (suggerito UserSuspended?). Questo mostrava che anche il nome del metodo era errato.
  4. Quarto tentativo (Utilizzo di UserSuspender.new(...).suspend come modello di oggetto servizio):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? 		 !user.admin? 		 !user.moderator?
        begin
            UserSuspender.new(
                user,
                Discourse.system_user,
                reason: "Tài khoản tạm khóa: Nghỉ phép dài hạn.",
                suspended_till: nil # Per la sospensione permanente
            ).suspend
            puts "Đã khóa tài khoản: #{user.username}"
        rescue => e
            puts "Lỗi khi khóa tài khoản #{user.username}: #{e.message}"
        end
      end
    end
    
    • Risultato: Questo comando è stato eseguito senza errori nella console. Ha stampato “Đã khóa tài khoản: [username]”.
    • Tuttavia, quando si controlla lo stato dell’utente nell’interfaccia utente di amministrazione o si interroga direttamente user.active nella console, gli utenti risultavano ancora active: true. Sono stati aggiornati solo suspended_at e suspended_till (ad esempio, suspended_at: "2025-05-26 00:37:01.406064419 +0000", suspended_till: nil). Gli account erano ancora in grado di accedere.
  5. Quinto tentativo (Impostazione diretta di active = false insieme ai campi di sospensione):

    admin_id_to_exclude = 100
    User.where.not(id: admin_id_to_exclude).each do |user|
      if user.active? 		 !user.admin? 		 !user.moderator?
        begin
            user.suspended_at = Time.current
            user.suspended_till = nil # Permanente
            user.custom_suspension_reason = "Chưa gia hạn tài khoản" # Motivo personalizzato
            user.active = false # Parte cruciale
            user.save!
            puts "Đã **khóa VĨNH VIỄN** và vô hiệu hóa tài khoản: #{user.username}"
        rescue => e
            puts "LỖI khi xử lý tài khoản #{user.username}: #{e.message}"
        end
      end
    end
    
    • Risultato: Anche questo comando è stato eseguito senza errori e ha stampato messaggi di successo.
    • Tuttavia, il risultato è stato lo stesso: active: true è rimasto e suspended_at/suspended_till sono stati aggiornati, ma gli account non sono stati effettivamente disa…
1 Mi Piace

Non credo che la disattivazione faccia parte del processo di sospensione dell’utente. Nell’interfaccia utente, dovresti premere separatamente il pulsante ‘disattiva’ se volessi che un utente sospeso di ritorno verificasse nuovamente la propria email.

Decidere se è quello che vuoi e affrontarlo come un’operazione separata potrebbe dare risultati migliori. :crossed_fingers:

Ci sono alcune indicazioni per le sospensioni di massa in questo argomento, se può essere d’aiuto Administrative Bulk Operations

Anche se, se provi quello e scopri che è obsoleto, faglielo sapere e dovrebbero essere in grado di aggiornare la guida di conseguenza.

1 Mi Piace