はじめに
掲示板に編集と削除機能を実装していきます。自分が作成した掲示板のみに、編集、削除ボタンを表示させるようにしましょう。
- 掲示板一覧画面、掲示板詳細画面にそれぞれ、編集ボタンと削除ボタンを実装しましょう。
- 編集ボタン、削除ボタンは、掲示板を作成した本人にしか表示されないようにしましょう。
- 削除ボタンをクリック後、確認アラートが表示され、その後「はい」をクリックすることで削除されるようにしましょう。
- 編集ページと新規作成ページのフォームは共通のパーシャルを使って共有させましょう。
- コントローラの各アクションで重複する処理は、まとめて記載するようにしましょう。
- 直接URLから他人の作成した掲示板の編集ページにアクセスした場合、404エラーが表示されるようにしましょう。
必要な作業
- ルーティングの設定
- コントローラの設定
- ビューファイルの設定
ルーティングの設定
edit
, update
, destroy
アクションを追加します。
Rails.application.routes.draw do
resources :boards, only: %i[index new create show edit update destroy] do
resources :comments, ojnly: %i[create], shallow: true
end
結局、resorcesすべてのアクションを使うことになりましたので、only: %i[index new create show edit update destroy]
は不要ですね。
Rails.application.routes.draw do
resources :boards do
resources :comments, ojnly: %i[create], shallow: true
end
コントローラの設定
class BoardsController < ApplicationController
before_action :set_board, only: %i[edit update destroy]
~~~~~~~~~~~~~~~~~一部省略~~~~~~~~~~~~~~~~~~~~
def edit; end
def update
if @board.update(board_params)
redirect_to @board, success: t('defaults.message.updated', item: Board.model_name.human)
else
flash.now[:danger] = t('defaults.message.not_updated', item: Board.model_name.human)
render :edit
end
end
def destroy
@board.destroy!
redirect_to boards_path, success: t('defaults.message.deleted', item: Board.model_name.human)
end
private
def set_board
@board = current_user.boards.find(params[:id])
end
def board_params
params.require(:board).permit(:title, :body, :board_image, :bord_image_cache)
end
コードを紐解く
before_action :set_board, only: %i[edit update destroy]
edit
, update
, destroy
アクションでは、他人の作成した掲示板を変更できないようにcurrent_user
を介して掲示板を取得しましょう。
def set_board
@board = current_user.boards.find(params[:id])
end
redirect_to @board, success: t('defaults.message.updated', item: Board.model_name.human)
redirect_to @board
で掲示板詳細画面に遷移します。
これは、redirect_to board_path(@board)
の省略形であると、Railsが良しなに解釈してくれています。
@board.destroy!
なぜ !
を付けているのでしょうか?
destroy
と destroy!
の違いは、削除に失敗した場合の振る舞いにあります。
前者はfalse
を返し、後者は例外を発生させます。
今回の場合だと、「掲示板を削除する」という行為が失敗する事を想定していません。
ですから、destroy!
と記載して、万が一処理に失敗した場合は、システムエラーとして処理を中断させて、おかしな挙動のまま機能を使わせないようにしています。
ビューファイルの設定
編集ボタン、削除ボタンの実装
編集のリンクを、掲示板編集画面へ遷移するようにパスを変更します。
削除リンクを、パスを変更、確認アラートが表示されるように記述を追加します。
<ul class='crud-menu-btn list-inline float-right'>
<li class="list-inline-item">
<%= link_to edit_board_path(board), id: "button-edit-#{board.id}" do %>
<%= icon 'fa', 'pen' %>
<% end %>
</li>
<li class="list-inline-item">
<%= link_to board_path(board), id: "button-delete-#{board.id}", method: :delete, data: {confirm: t('defaults.message.delete_confirm')} do %>
<%= icon 'fas', 'trash' %>
<% end %>
</li>
</ul>
掲示板一覧画面、掲示板詳細画面にボタンを表示
<%= render 'crud_menus', board: board if current_user.own?(board) %>
<%= render 'crud_menus', board: board if current_user.own?(board) %>
掲示板編集画面のビューを作成します。
掲示板新規作成画面のビューとほとんど同じなのでコピーしてきます。
content_for
の部分だけ、掲示板詳細画面と同じく個別のタイトルが出力されるように変更しておきましょう。
<% content_for(:title, @board.title) %>
<div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<h1><%= t('.title') %></h1>
<%= render 'form', { board: @board } %>
</div>
</div>
</div>
国際化対応
ja.ymlファイルに、メッセージを追記しておきましょう。
ja:
defaults:
message:
updated: "%{item}を更新しました"
not_updated: "%{item}を更新できませんでした"
deleted: "%{item}を削除しました"
delete_confirm: '削除しますか?'
boards:
edit:
title: '掲示板編集'
おわりに
今回の学習では以下の要点をしっかりマスターしておきましょう。
data-confirm
によるアラートの表示の仕方create
,create!
の違い(破壊的メソッド)- 他人の掲示板を編集・削除しようとした際の制御(Boardでなくcurrent_user.boardsから取得)
コメント