👔
報告機能の実装
この記事で分かること
- ユーザーの投稿内容を管理者に不適切な発言として報告できる
前提条件
- ユーザー用のdeviseと管理者用のdeviseが実装済み
- 完成イメージのようなリンクを貼る箇所を確立している
- アソシエーション済み (記事では割愛)
完成イメージ
ユーザー側
管理者側
ER図
テーブル
実装手順
- reportsモデル・コントローラの作成
- routeingの設定
- 既存のページにリンク先を設定
- public/reports/showページ作成
- public/reports/completeページの作成
- admin/reports/indexの作成
実装方法
実装手順に沿って紹介します。
reportsモデル・コントローラの作成
以下の記述でモデルとコントローラを準備しました。
$ rails g model Report user_id:integer item_id:integer report:text
$ rails g controller reports show
routeingの設定
私は以下の記述で実装しました。
config/routes
scope module: :public do
root to: "homes#top"
get "/about" => "homes#about"
get "search" => "searches#search"
resources :items, only: [:new, :index, :show, :create, :destroy, :create] do
+ resource :reports, only: [:new, :create]
+ get :complete, on: :member
end
resources :users, only: [:show, :edit, :update] do
end
namespace :admin do
root to: "homes#top"
get "search" => "searches#search"
+ resources :reports, only: [:index]
resources :users, only: [:show, :edit, :update]
end
controllerを作成
public/reports_controller
class Public::ReportsController < ApplicationController
before_action :authenticate_user!
def new
@report = Report.new
@item = Item.find(params[:item_id])
end
def create
item = Item.find(params[:item_id])
report = current_user.reports.new(report_params)
report.item_id = item.id
if report.save
item.update(status: 0)
flash[:notice] = "管理者に報告しました"
redirect_to complete_item_path(item)
else
@report = Report.new
@item = Item.find(params[:item_id])
flash[:alert] = "正しい内容を入力してください"
render "new"
end
end
private
def report_params
params.require(:report).permit(:report)
end
end
admin/reports_controller
class Admin::ReportsController < ApplicationController
before_action :authenticate_admin!
def index
@reports = Report.order("created_at DESC").page(params[:page])
end
end
viewを作成
public/items/show
<div class='container py-5 px-sm-0'>
<div class='row'>
<div class='col-md-3'>
<%= render 'public/users/info', user: @user %>
<div class= "row d-none d-md-block">
<%= render 'form', item: @new_item %>
</div>
<%= render 'public/genres/genre_search', genres: @genres %>
</div>
<div class='col-md-8 offset-md-1 mt-3'>
<h4><%= @user.name %>さんの投稿</h4>
<div class="col-12 table-responsive-sm">
<!-- テーブル略 -->
</div>
<div class="row justify-content-around text-center align-middle">
+ <div class="col-lg-5 col-md-7 col-sm-7 col-8 mb-lg-5 my-sm-3 my-3 background"><strong><%= link_to "不適切な投稿として報告する" ,new_item_reports_path(@item), class: "text-dark" %></strong></div>
<div class="col-lg-5 col-md-7 col-sm-7 col-8 mb-lg-5 my-sm-3 mb-4 background"><span>投稿日 </span><%= @item.created_at.strftime('%Y/%m/%d') %></div>
</div>
<!-- 以下略 -->
public/reports/new
<div class= "container py-5 px-sm-0">
<div class= "row">
<div class='col-md-8 col-12 offset-md-2'>
<h4>投稿内容</h4>
<div class="col-12 table-responsive-sm">
<table class="table text-nowrap table-bordered">
<!-- テーブル略 -->
</table>
</div>
</div>
</div>
<div class= "row">
<div class= "col-6 offset-3 mt-5">
<h4>管理者に報告する</h4>
<%= form_with model: [@item, @report] do |f| %>
<%= f.text_area :report, class: 'form-control', rows: '6', placeholder: "報告内容を記載" %><br>
<%= f.submit "報告する", class: "btn btn-outline-success" %>
<% end %>
</div>
</div>
</div>
public/items/complate
<div class="container">
<div class="row justify-content-center">
<div class="col-12 mb-5"></div>
<h4 class="my-5 text-center align-center">ご報告ありがとうございました!</h4>
<div class="col-12 mb-5"></div>
</div>
<div class="row justify-content-center">
<div class="col-12 mb-5"></div>
<div class="my-5 text-center align-center"><%= link_to "マイページに戻る" ,user_path(current_user), class: "btn btn-success" %></div>
<div class="col-12 mb-5"></div>
</div>
</div>
admin/reports/index
<div class= "container py-5 px-sm-0">
<% if @reports.blank? %>
<h4 class= "col-4 offset-4 mt-5 background text-center">報告はありません</h4>
<% end %>
<% @reports.each do |report| %>
<div class= "row">
<div class="col-lg-8 col-12 offset-lg-2">
<div class="col-12 table-responsive-sm">
<table class="table text-nowrap table-bordered">
<!-- 不適切な投稿のテーブル -->
</table>
</div>
</div>
</div>
<div class= "row justify-content-around text-center align-middle">
<div class="col-lg-2 col-md-5 col-sm-4 col-8 mb-lg-5 my-sm-3 my-3 background"><%= report.item.status_i18n %></div>
<div class="col-lg-2 col-md-5 col-sm-4 col-8 mb-lg-5 my-sm-3 my-3 background"><span>投稿日 </span><%= report.item.created_at.strftime('%Y/%m/%d') %></div>
</div>
<div class= "row">
<div class= "col-lg-8 col-12 offset-lg-2">
<div class="col-12 table-responsive-sm">
<table class="table text-nowrap table-bordered">
<!-- 報告者のテーブル -->
</table>
</div>
</div>
</div>
<div class= "row">
<div class="col-md-2 col-6 offset-md-8 offset-3 mb-4 mt-lg-0 mt-3 align-middle text-center background"><span>報告日 </span><%= report.created_at.strftime('%Y/%m/%d') %></div>
</div>
<% end %>
<div class="row justify-content-center">
<%= paginate @reports %>
</div>
</div>
最後にヘッダーにリンクを貼れば完成です。
感想
報告機能はadminとpublicに分かれているので難しそうに感じました。しかし実装方法は、コメント機能などと似たような感じで実装はしやすかったです。
この記事をかいた人
23/6/1にDWCに入学し、主にRailsの学習に取り組みました。卒業が近づきこれから何で学習をするか悩んだときに、技術ブログをしようと考えました。初心者ですがよろしくお願いします。
Discussion