皆さん、こんにちは。
RailsコンソールからDiscourseインスタンス(バージョン3.5.0.beta5-dev)でユーザーを一括停止/非アクティブ化しようとしていますが、解決しない問題に直面しています。管理者アカウント(hoangthai、ユーザーID 100)を除外し、他のすべてのアクティブな非管理者/非モデレーターユーザーを、カスタム理由「Chưa gia hạn tài khoản」(アカウント更新保留中)で永久に停止しようとしています。
一般的なDiscourseコンソールコマンドとデバッグの提案に基づいていくつかのアプローチを試しましたが、suspended_atとsuspended_tillが設定されていても、アカウントはactive: trueのままです。
これまでに試したことと、エラー/結果の内訳は次のとおりです。
目標: すべてのユーザーを(hoangthai、ID 100を除く)理由「Chưa gia hạn tài khoản」(アカウント更新保留中)で永久に停止すること。
試行と問題点:
-
最初の試行(
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。" # 最初の理由の試み 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- 結果:
NoMethodError: undefined method 'suspend_reason=' for an instance of User(suspended_at=が提案されました)。これは、suspend_reasonが正しい属性ではないことを示しています。
- 結果:
-
2回目の試行(新しいバージョンで推奨されている
UserSuspension.suspend_userを使用):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- 結果:
NameError: uninitialized constant UserSuspension(UserSuspenderが提案されました)。これは、クラス名が間違っていることを示しています。
- 結果:
-
3回目の試行(クラス名を
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( # まだ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- 結果:
NoMethodError: undefined method 'suspend_user' for class UserSuspender(UserSuspended?が提案されました)。これは、メソッド名も間違っていることを示しています。
- 結果:
-
4回目の試み(サービスオブジェクトパターンとして
UserSuspender.new(...).suspendを使用):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: "アカウント一時停止:長期休暇のため。", suspended_till: nil # 永久停止の場合 ).suspend puts "アカウントを停止しました:#{user.username}" rescue => e puts "アカウント#{user.username}の停止中にエラーが発生しました:#{e.message}" end end end- 結果: このコマンドはコンソールでエラーなしで実行されました。 "アカウントを停止しました:[ユーザー名]"と出力されました。
- ただし、管理UIでユーザーのステータスを確認するか、コンソールで
user.activeを直接クエリすると、ユーザーは依然としてactive: trueと表示されました。suspended_atとsuspended_tillのみが更新されました(例:suspended_at: "2025-05-26 00:37:01.406064419 +0000", suspended_till: nil)。アカウントはまだログインできました。
-
5回目の試み(停止フィールドとともに
active = falseを直接設定):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 # 永久 user.custom_suspension_reason = "アカウントが更新されていません" # カスタム理由 user.active = false # 重要な部分 user.save! puts "アカウントを**永久にロック**し、無効にしました:#{user.username}" rescue => e puts "アカウント#{user.username}の処理中にエラーが発生しました:#{e.message}" end end end- 結果: このコマンドもエラーなしで実行され、成功メッセージが出力されました。
- ただし、結果は同じでした:
active: trueのままで、suspended_at/suspended_tillが更新されましたが、アカウントは実際にはディアク…