#コントローラーに編集と削除を追加
###ルーティングの設定
Rails.application.routes.draw do
root 'static_pages#top'
get 'login', to: 'user_sessions#new'
post 'login', to: 'user_sessions#create'
delete 'logout', to: 'user_sessions#destroy'
resources :users, only: %i[new create]
resources :boards do
resources :comments, only: %i[create], shallow: true
end
end
・前回はonly: %i[index new create show] で、4つ指定したいたが今回は「destroy」「edit」「update」を加えるのでonlyで範囲を指定をしない。
###boardコントローラーの設定
class BoardsController < ApplicationController
before_action :find_board, only: [: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 find_board
@board = current_user.boards.find(params[:id])
end
before_action :set_board, only: %i[edit update destroy]
「edit(編集画面の表示)」「update(更新処理)」「destroy(削除処理)」アクションでは投稿を基に行う作業として共通しているので、「before_action」でまとめている。
*before_actionはコントローラー内の全てのアクションが実行される前に、その後に続くメソッド(ここではfind_board)が実行される.
@board = current_user.boards.find(params[:id])
urlのパラメーターから受け取った投稿(params[:id])を取得して,その中にある外部キー「user_id」にログインしているユーザー(current_user)のidを代入している。これによって投稿と投稿したユーザーが一致しているのかを検証してくれる。*user_idを取得するのが大事
@board.update(board_params)
updateメソッドで更新処理を行なっている。
redirect_to @board
redirect_to board_path(@board)の省略。投稿詳細ページに飛ぶ。
@board.destroy!
destroyメソッドで投稿を削除している。
*destroyとdestroy!メソッドの違いは処理後の挙動。destroyだと失敗した後に「処理が失敗しました」などのエラー目セージを入れたり、renderを使って前画面に戻したりできる。しかし削除処理に失敗するという可能性がないので「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) %>
・パーシャルの'crud_menus'を呼び出し、model: boardに@boardを代入している。
・「if current_user.own?(@board)」はuserモデルで作成した「own?(object)」メソッドを使っている。
*「curremt_user」のidと「@board」のuser_idが一致を検証している。これがあることでログインしているユーザーと投稿作成した人が同じかを確認している。
def own?(object)
self.id == object.user_id #selfは省略できる
end
#掲示板編集のビューを追加
<% 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>
<%= render 'form', { board: @board } %>
・投稿フォームのパーシャル(app/views/boards/_form.html.erb)を呼び出している。{ board: @board }の「board」に、「find_board」アクションの中の「 @board = current_user.boards.find(params[:id])」の@boardを代入している。これにより、urlのパラメーターから編集する投稿を取得している。