안녕하세요 여러분,
Discourse 인스턴스(버전 3.5.0.beta5-dev)에서 Rails 콘솔을 통해 사용자를 일괄 정지/비활성화하려는 시도에 지속적인 문제가 발생하고 있습니다. 관리자 계정(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이 올바른 속성이 아니라는 것을 의미했습니다.
- 결과:
-
두 번째 시도 (신규 버전에 권장되는
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권장). 이는 클래스 이름이 올바르지 않다는 것을 의미했습니다.
- 결과:
-
세 번째 시도 (클래스 이름을
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?권장). 이는 메서드 이름도 올바르지 않다는 것을 보여주었습니다.
- 결과:
-
네 번째 시도 (서비스 객체 패턴으로
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: "Tài khoản tạm khóa: Nghỉ phép dài hạn.", suspended_till: nil # 영구 정지를 위해 ).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- 결과: 이 명령어는 콘솔에서 오류 없이 실행되었습니다. "Đã khóa tài khoản: [username]"이 출력되었습니다.
- 그러나, 관리자 UI에서 사용자 상태를 확인하거나 콘솔에서
user.active를 직접 쿼리했을 때, 사용자들은 여전히active: true로 표시되었습니다.suspended_at와suspended_till만 업데이트되었습니다(예:suspended_at: "2025-05-26 00:37:01.406064419 +0000", suspended_till: nil). 계정들은 여전히 로그인할 수 있었습니다.
-
다섯 번째 시도 (정지 필드와 함께
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 = "Chưa gia hạn tài khoản" # 커스텀 사유 user.active = false # 핵심 부분 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- 결과: 이 명령어도 오류 없이 실행되어 성공 메시지가 출력되었습니다.
- 그러나 결과는 동일했습니다:
active: true가 유지되었고,suspended_at/suspended_till은 업데이트되었지만, 계정들은 실제로 비활성화되지 않았으며 로그인도 차단되지 않았습니다.
현재 상황:
관리자 UI(관리자 → 사용자 → 정지)를 통해 수동으로 사용자를 정지시키면 올바르게 정지됩니다(예: 이전 스크린샷에 표시된 "Tạm khóa bởi: hoangthai, Lý do: Chưa gia hạn tài khoản"와 같이, 로그인이 불가능해짐). 이는 핵심 기능이 정상 작동한다는 것을 확인시켜 줍니다.
Discourse 3.5.0.beta5-dev에서 사용자를 프로그래매틱하게 정지/비활성화하는 데 특정한 API 미묘한 차이가 있어서 제가 놓치고 있거나, 캐시 문제가 제대로 해제되지 않거나, 실행되어야 할 백그라운드 작업이 있는 것 같습니다.
Discourse 3.5.x 베타 버전이나 깊은 Rails 콘솔 지식이 있는 분 중, 사용자의 로그인을 실제로 방지하고 active 상태를 false로 설정하는 일괄 영구 정지를 올바르게 수행하는 방법에 대해 조언해 주실 수 있을까요?
시간 내어 도와주셔서 감사합니다!