💨

[Rails]会員管理機能: Userの通報機能作成② adminからの操作

2023/03/16に公開

では、続きを行なっていきます。
前回はuserが userを通報するまで行いました。
ここからは管理者側でのコントロールと、処理を行います。

https://zenn.dev/airiswim/articles/c3e7e6d47cab71

次回は利用停止になったアカウントの投稿は閲覧不能に、と自動利用停止です!!


管理側作成

admin / reports_controller

管理側の通報管理画面の作成

class Admin::ReportsController < ApplicationController
  def index
    @reports = Report.all
  end

  def show
    @report = Report.find(params[:id])
  end

  def update
    @report = Report.find(params[:id])
    if @report.update(report_params)
      redirect_to admin_reports_path
    end
  end

  private

  def report_params
    params.require(:report).permit(:checked)
  end
end

メソッドを作成!

通報件数をカウントし表示するためのメソッドを作成します。
※私はカウントカラムを作成していないのでこうするけど、色々やり方はありそう!!

class Report < ApplicationRecord
  belongs_to :reporter, class_name: "User"
  belongs_to :reported, class_name: "User"

  # reporter_idがuser_idである通報の件数を返すクラスメソッド(ここを追記)
  def self.reported_count(user_id)
    where(reported_id: user_id).count
  end
end

report index.html.erb

index.html
<%= link_to "会員一覧へ",admin_root_path,class: "btn btn-success" %>
<div class="card">
  <div class="card-body">
    <h3 class="card-title">通報一覧</h3>
    ※番号から通報詳細へ飛びます。
    <div class="table-responsive">
      <table class="table table-hover">
        <thead>
          <tr>
            <th>通報ID</th>
            <th>通報日</th>
            <th>会員名</th>
            <th>通報者</th>
            <th>通報された回数</th>
            <th>管理者check</th>
          </tr>
        </thead>
        <tbody>
          <% @reports.each do |report| %>
            <tr>
              <td><%= link_to report.id, admin_report_path(report) %></td>
              <td><%= report.created_at %></td>
              <td><%= report.reported.full_name %></td>
              <td><%= report.reporter.full_name %></td>
              <td><%= Report.where(reported_id: report.reported_id).count %></td>
              <td>
                <% if report.checked %>
                  <span class="badge badge-success">確認済み</span>
                <% else %>
                  <span class="badge badge-danger">未確認</span>
                <% end %>
              </td>
            </tr>
          <% end %>
        </tbody>
      </table>
    </div>
  </div>
</div>


これでもいいのですが、私は気になる点が…
時間表記にUTCとかつくの嫌だ!!! そんな時はこのような設定をしましょう。

  1. config/application.rb ファイルに以下のように記述
config.time_zone = 'Tokyo'
config.active_record.default_timezone = :local
  1. ビューで表示するとき: created_at メソッドなどを使用して日付をフォーマット
<td><%= report.created_at %></td>
# 上記を以下のように変換
<td><%= report.created_at.in_time_zone('Tokyo').strftime('%Y-%m-%d %H:%M:%S') %></td>

report show.html.erb

show.html
<div class="row justify-content-center align-items-center mb-4">
  <div class="col-md-4 text-center">
    <% if @user.image.attached? %>
      <%= image_tag @user.image, size: "150x150", class: "img-fluid rounded-circle" %>
    <% else %>
      <%= image_tag 'no_image.png', size: "150x150", class: "img-fluid rounded-circle" %>
    <% end %>
    <h4 class="mt-3"><strong><%= @user.first_name %> <%= @user.last_name %></strong></h4>
  </div>
</div>
<div class="row justify-content-center">
  <div class="col-md-6">
    <h3 class="text-center">会員情報編集</h3>
    <div class="form-group text-center">
      <div class="mt-3">
        <strong>通報された回数:</strong>
        <%= Report.reported_count(@user.id) %>
      </div>
    </div>
    <%= form_with model: @user, url: admin_user_path(@user), method: :patch do |f| %>
      <div class="form-group text-center">
        <br>
        <div class="custom-control custom-radio custom-control-inline">
          <%= f.radio_button :user_status, :available, id: "user_status_0", class: "custom-control-input" %>
          <%= f.label I18n.t("enums.user.user_status.available"), class: "custom-control-label", for: "user_status_0" %>
        </div>
        <div class="custom-control custom-radio custom-control-inline">
          <%= f.radio_button :user_status, :suspended, id: "user_status_1", class: "custom-control-input" %>
          <%= f.label I18n.t("enums.user.user_status.suspended"), class: "custom-control-label", for: "user_status_1" %>
        </div>
      </div>
      <div class="form-group text-center">
        <%= f.submit "ステータスを更新", class: "btn btn-primary mx-auto" %>
      </div>
    <% end %>
  </div>
</div>

  • 管理者が通報について確認したかどうかを表すcheckedカラムを前回作成してましたね。
    defaultはfalse(未確認)で設定しています。

  • I18n.t("enums.user.user_status.suspended")
    I18nにて多言語対応(日本語化) しているので、このメソッドを使用して日本語訳を取得が可能です。
    I18nについての詳しくはコチラがわかりやすかったのでみてみてください!
    Rails I18nの便利機能について


通報を受けてUser_statusの管理者による更新

admin/users_controller.rb

ここは今回特に変わった記述はありません!!

class Admin::UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end
  # user_status管理
  def edit
    @user = User.find(params[:id])
  end

  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      redirect_to admin_reports_path
    else
      render "show"
    end
  end

  private

  def user_params
    params.require(:user).permit(:user_status)
  end
end

admin/users/show. ①

一旦簡単に、user_statusや通報回数などの今回の必須機能(変更)のみつけていきます!!

users/show. ①
<div class="row justify-content-center align-items-center mb-4">
  <div class="col-md-4 text-center">
    <% if @user.image.attached? %>
      <%= image_tag @user.image, size: "150x150", class: "img-fluid rounded-circle" %>
    <% else %>
      <%= image_tag 'no_image.png', size: "150x150", class: "img-fluid rounded-circle" %>
    <% end %>
    <h4 class="mt-3"><strong><%= @user.first_name %> <%= @user.last_name %></strong></h4>
  </div>
</div>
<div class="row justify-content-center">
  <div class="col-md-6">
    <h3 class="text-center">会員情報編集</h3>
    <div class="form-group text-center">
      <div class="mt-3">
        <strong>現在のステータス:</strong>
        <%= @user.user_status_i18n %>
      </div>
    </div>
    <%= form_with model: @user, url: admin_user_path(@user), method: :patch do |f| %>
      <div class="form-group text-center">
        <br>
        <div class="custom-control custom-radio custom-control-inline">
          <%= f.radio_button :user_status, :available, id: "user_status_0", class: "custom-control-input" %>
          <%= f.label I18n.t("enums.user.user_status.available"), class: "custom-control-label", for: "user_status_0" %>
        </div>
        <div class="custom-control custom-radio custom-control-inline">
          <%= f.radio_button :user_status, :suspended, id: "user_status_1", class: "custom-control-input" %>
          <%= f.label I18n.t("enums.user.user_status.suspended"), class: "custom-control-label", for: "user_status_1" %>
        </div>
      </div>
      <div class="form-group text-center">
        <%= f.submit "ステータスを更新", class: "btn btn-primary mx-auto" %>
      </div>
    <% end %>
  </div>
</div>


さあ、ここまでできたら良い、と思いきや、まだです。

利用停止になったアカウントの投稿は閲覧不能に

利用停止された人の投稿が見れてたり、イヴェントが参加可能になっていたら困るよね。

ここでは例にコードを変えてみます。

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

このように変更したいので、メソッドを作成してやっていきたいと思う。

また長くなるので次回。

Discussion