📖
[Rails]会員管理:通報機能③自動削除
では前回までこのようにやってきたので、今日も進めましょう。
利用停止の人の投稿は閲覧不可に設定しよう。
前回最後で例に出したのは…投稿(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を使用すると、データが増える場合がある。
これを修正方法は、いくつかあるが、試したものを二つのせる。
-
joinsの代わりにincludesを使用
includesは、Eager Loadingを行い、関連するモデルのデータを一度に取得することができる。
# joinsの場合
@users = User.joins(:posts).where(posts: { published: true })
# includesを使用する場合
@users = User.includes(:posts).where(posts: { published: true })
でも、DBには負担がでかい!!!!
関連付けたものの情報を一旦全て取ってきてその中から探すから、あまりおすすめではない。
-
条件を絞り込む
クエリに対して余分な条件が含まれている場合は、条件を絞り込んで、不要なデータを取得しないようにする。
例えば、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回通報されたら、自動的に利用停止になるように設定していきます!
多くなると管理人でも追えなくなりますからね。作ろう。
カウントカラムは追加していなかったので、メソッドを作成して実装していきます。
- user.rbに通報回数のメソッドと、3回以上通報されたかの確認メソッド作成。
# 自動利用停止メソッド1 通報回数のカウント
def report_count
Report.where(reported_id: id).count
end
# 自動利用停止メソッド2 3回以上通報されたかチェック
def exceeded_report_limit?
report_count >= 3
end
- 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