이메일 패턴에 일치하는 사용자 일괄 삭제

다음과 같은 이메일 패턴에 해당하는 사용자를 일괄 삭제하고 싶습니다:

  • *.xyz
  • *.fun
  • 등..

현재까지는 User.find(UserEmail.where("email like '%.fun'").pluck(:user_id)).count를 시도해 보았습니다. 하지만 .where() 이후에는 destroy_all 함수를 사용할 수 없습니다…

도움 주실 수 있으신가요?
감사합니다.

저도 같은 작업을 하고 싶습니다. 해당 사용자들의 게시물/토픽도 모두 삭제해야 합니다.

User.joins(:user_emails)
  .where('lower(user_emails.email) LIKE ?', '%domain.com')

특히, 백분율 기호(%)는 어떤 문자든 0개 이상을 나타내는 와일드카드입니다. 따라서 %domain.com은 domain.com으로 끝나는 이메일을 의미합니다.

User#destroy 대신 UserDestroyer를 사용하는 것이 좋습니다:

UserDestroyer.new(Discourse.system_user)
  .destroy(user, delete_posts: true)

이렇게 하면 시스템 사용자가 해당 사용자와 모든 게시물을 삭제합니다.

요약하면 다음과 같습니다:

User.joins(:user_emails)
  .where('lower(user_emails.email) LIKE ?', '%domain.com')
  .find_each do |user|
    UserDestroyer.new(Discourse.system_user).destroy(user, delete_posts: true)
  end

이 작업은 되돌릴 수 없음을 유의하세요. 실제로 삭제하기 전에 쿼리로 선택된 사용자를 확인하는 것이 좋습니다. 또한, 많은 수의 사용자를 삭제하거나 해당 사용자에게 게시물이 매우 많은 경우 성능에 어떤 영향을 미칠지는 확실하지 않습니다.

다른 참고 사항으로, Anonymizing Users in Discourse 이 대안이 될 수 있는지 모르겠습니다.

안녕하세요 @xrav3nz! 이 답변 정말 훌륭합니다! :open_mouth:
제가 필요한 바로 그 내용이에요. 지금 바로 시도해볼게요. 물론 제안해 주신 대로 먼저 기본 count()로 수량을 확인한 후에요.

한 가지 질문이 있는데요, delete_post: true가 false보다 더 맞지 않을까요?

제 사용 사례는 아주 간단합니다. @gerhard 덕분에 오래된 phpBB를 가져왔는데 완벽하게 잘 작동했어요. 하지만 이 오래된 포럼은 가짜 계정으로 완전히 오염되어 있습니다. 그들은 어떤 메시지도 게시하지 않았어요. 모든 이메일 주소가 .fun 또는 .xyz로 끝납니다.

네, 맞습니다! 제 오타였어요!