🐥

[Rails]会員管理機能: Userの通報機能作成①user通報

2023/03/15に公開

今回は通報機能について。

"userが、userを通報できる"と言うことは、follow・follwer機能と同じですね!!!

(こんな単純なことに気づかず、最初は違った発想をしていて半日以上無駄にしてしまったyo。笑)

中間テーブルを作成し、そこに通報したUSERと通報されたUSERを入れて通報状態を管理!!
ほか通報理由などもカラムとして入れて管理側で利用停止処理ができるようにしましょう。

3回で自動的に利用停止処理も入れたいと思います。

必要なテーブル、カラムを揃えよう

Report テーブル、カラム

# 通報モデル:migration file
      t.integer :reporter_id
      t.integer :reported_id
      t.text :reason, null: false
      t.boolean :checked, default: false

  • reporter_id :通報したユーザー
  • reported_id :通報されたユーザー
  • reason :通報理由(内容)
  • checked:管理者が確認したかどうかのフラグ(デフォルト値:false)
User テーブル、カラム, statusのenum設定

 t.integer "user_status", default: 0
  • userにはstatusが必要になりますね。
    => enum (0: available 利用可能 / 1. suspended 利用停止)で設定。

enumの設定。

# user モデルfile
class User < ApplicationRecord
  enum status: { available: 0, suspended: 1 }
end

ja.ymlにも記述。

ja:
    activerecord:
      errors:
        models:
          admin:
            attributes:
              email:
                taken: 'そのメールアドレスは既に使用されています'
          user:
            attributes:
              email:
                taken: 'そのメールアドレスは既に使用されています'
              password:
                blank: 'は内容が入力されていません'

    enums:
      post:
        post_status:
          published: "公開"
          draft: "下書き保存"
     # ここからした!!
      user: 
        status:
          available: "利用可能"
          suspended: "利用停止中"

associationの記述

User.rb

has_many :reporter, class_name: "Report", foreign_key: "reporter_id", dependent: :destroy
has_many :reported, class_name: "Report", foreign_key: "reported_id", dependent: :destroy

Report.rb

belongs_to :reporter, class_name: "User"
belongs_to :reported, class_name: "User"

controller

  • Reported controllerの作成。

他はできているものとして通報ののみ今回は記載。

routing

#route.rb
scope module: :public do
 resource :users, only: [] do
      get "my_page" => "users#show"
      get "profile/:user_id" => "users#profile", as: "profile"
      # added these
      post "profile/:user_id/report" => "reports#create", as: "profile_report"
      get "profile/:user_id/report/new" => "reports#new", as: "profile_reports_new"
      get "information/edit" => "users#edit"
      patch "information" => "users#update"
    end

end


namespace :admin do
    resources :reports, only: [:index, :show, :update]
end


User(public)から作成

public / reports_controller

class Public::ReportsController < ApplicationController
  def new
    @report = Report.new
    @user = User.find(params[:user_id])
  end

  def create
    @user = User.find(params[:user_id])
    @report = Report.new(report_params)
    @report.reporter_id = current_user.id
    @report.reported_id = @user.id

    if @report.save
      redirect_to profile_users_path(@user)
    else
      render "new"
    end
  end

  private

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

  • @report.reporter_id = current_user.id
    通報者(reporter_id)にcurrent_user.idを代入
  • @report.reported_id = @user.id  
    通報される人(reported_id)に定義した@user.idを代入

Viewの作成

では通報ボタンを実装していきます。

  • mypage以外で、通報ボタンを表示させるように設定します。
  • また、同じ人を2回通報できないように設定。
<% if @user != current_user %>
  <% if current_user.reporter.exists?(reported_id: @user.id) %>
    <%= button_tag "通報済み", class: "btn btn-secondary", disabled: true %>
  <% else %>
    <%= link_to "ユーザーを通報", profile_reports_new_users_path(@user), class: "btn btn-danger" %>
  <% end %>
<% end %>

  • current_user.reporter.exists?(reported_id: @user.id)
    => 現在のユーザーが既にそのユーザーを報告しているかどうかを確認

[ public/reports/new.html.erb ]

通報作成フォーム

<div class="container">
  <div class="row justify-content-center">
    <div class="col-md-6">
      <h3 class="text-center">通報</h3>
      <p class="text-center">通報理由を以下にご記入ください。</p>
      <%= form_with model:[@user, @report],url: users_reports_path(@user), class: "my-4" do |f| %>
        <div class="form-group d-flex justify-content-center">
          <%= f.text_area :reason, rows:'3', class:"form-control" %>
        </div>
        <div class="form-group d-flex justify-content-center">
          <%= f.submit "通報する", class: "btn btn-danger" %>
        </div>
      <% end %>
    </div>
  </div>
</div>


今日はこの通報し終えるまで!!!

次は管理者側でのコントロールと、自動的なアカウント利用停止処理を行います。

bye~~

Discussion