📖

[Rails]会員管理:通報機能③自動削除

2023/03/17に公開

では前回までこのようにやってきたので、今日も進めましょう。

利用停止の人の投稿は閲覧不可に設定しよう。

前回最後で例に出したのは…投稿(post)

def index
    #@posts = Post.published
    #上記コードを以下のコードに変えて利用可能のみ表示
    @posts = Post.joins(:user).where(post_status: :published).where(user: { user_status: 0 })
  end

※publishedは投稿です。(enum使用しているので。)
でもこれは長いしめんどうだよね。と言うことで。

メソッドの作成

まずは Post モデルに、利用停止になったユーザーの投稿を非表示にするためのスコープを追加

class Post < ApplicationRecord
:
:
  enum post_status: [:draft, :published]

  scope :published, -> { where(post_status: :published) }
  scope :by_active_users, -> { joins(:user).where(users: { user_status: 0 }) }
  scope :visible, -> { published.by_active_users }
end

  • 下段visible スコープにより、利用停止になったユーザーの投稿を非表示にすることができる。
    => published スコープby_active_users スコープを組み合わせて作成。

controller

と言うことで、こんなにコンパクトに。

def index
    @posts = Post.visible
end
Eventも同じようにできます。
  • scope作成
scope :by_active_users, -> { joins(:users).select("events.*, users.user_status").where(users: { user_status: 0 }).distinct }
  scope :upcoming, -> { where("date >= ?", Time.zone.now).order(date: :asc) }
  scope :visible, -> { by_active_users.upcoming }
  • controller
def index
    # @events = Event.where("date >= ?", Time.now).page(params[:page]).per(8)
    @events = Event.visible.page(params[:page]).per(8)
end

⚠️joinについて

Railsでjoinsを使用すると、データが増える場合がある。
これを修正方法は、いくつかあるが、試したものを二つのせる。

  1. joinsの代わりにincludesを使用
    includesは、Eager Loadingを行い、関連するモデルのデータを一度に取得することができる。
# joinsの場合
@users = User.joins(:posts).where(posts: { published: true })

# includesを使用する場合
@users = User.includes(:posts).where(posts: { published: true })

でも、DBには負担がでかい!!!!
関連付けたものの情報を一旦全て取ってきてその中から探すから、あまりおすすめではない。

  1. 条件を絞り込む
    クエリに対して余分な条件が含まれている場合は、条件を絞り込んで、不要なデータを取得しないようにする。
    例えば、joinsを使用して関連するデータを取得する場合、余分な条件があると、不要なデータが取得されてしまう。これがデータが増える(複製) される原因になる。
# 関連するデータ全てを取得する場合
@users = User.joins(:posts).where(posts: { published: true })

# 関連するデータを絞り込む場合
@users = User.joins(:posts).where(posts: { published: true, user_id: current_user.id })

今回は2番目のこの方法で実行した。この方がDBへの負担も少なく速度も上がる。


自動的に利用停止にすることができる!

3回通報されたら、自動的に利用停止になるように設定していきます!
多くなると管理人でも追えなくなりますからね。作ろう。

カウントカラムは追加していなかったので、メソッドを作成して実装していきます。

  1. user.rbに通報回数のメソッドと、3回以上通報されたかの確認メソッド作成。
# 自動利用停止メソッド1  通報回数のカウント
  def report_count
    Report.where(reported_id: id).count
  end

  # 自動利用停止メソッド2  3回以上通報されたかチェック
  def exceeded_report_limit?
    report_count >= 3
  end
  1. report.rbで、通報が作成された後に、update_user_statusメソッドを呼び出すように設定。
    このメソッドは、通報されたユーザーが利用停止状態になるように更新する。
# report.rb

  after_create :update_user_status

  def update_user_status
    reported_user = User.find(reported_id)
    if reported_user.report_count >= 3
      reported_user.update(user_status: :suspended)
    end
  end

  • Reportモデルに新しいレコードが作成されるたびに、update_user_statusメソッドが呼び出され、exceeded_report_limit?メソッドがtrueを返すと、
    reported_userのuser_statusがsuspendedに更新され流ように設定した。

  • 利用停止になったユーザーは、not_suspendedスコープで検索対象外となるため、
    アプリケーションの他の部分でも自動的に制限される。


これにて、会員管理:通報機能については終了!!!!

Discussion