【Rails】投稿編集(edit,update)、投稿削除(destroy)の実装!
こんにちは!
web系エンジニアを目指して学習中のsiと申します^ ^
この記事の対象者
- 投稿編集機能(edit,update)を実装したい方
- 投稿削除機能(destroy)を実装したい方
今回の記事では、投稿編集・投稿削除機能の実装方法について解説していきます!
今回実装するアクション
アクション名 | 使用方法 |
index | リソースの一覧表示 |
show | リソースの詳細表示 |
new | リソースの新規作成 |
edit | リソースの編集 |
create | リソースを新規作成して保存する |
update | リソースの更新 |
destroy | リソースの削除 |
基本的な7つのアクションについて気になる人は、以下の記事を参考にしてみてください!
※この記事で出てくる「%」はプロンプトなので実際に入力する必要はありません
目次
マシンスペック
参考までに私のマシンスペックをご紹介しておきます。
- macOS Big Sur 11.5.1
- Macbook Pro(13-inch,2020,Four Thunderbolt 3 ports)
- intel Core i5
- メモリ 16GB
- ストレージ 512GB
- 使用シェル zsh
投稿編集・削除機能の実装
この記事は下記記事の続きになります!
当記事では投稿モデル・コントローラの名称を「Output」としてますが、他の名称でも問題ありません。
⇨「Post」、「Tweet」など
1 editページの作成・編集
・edit、updateアクションの追加
# app/views/controller/outputs_comtroller.rb
def edit
@output = Output.find(params[:id])
# 編集リンクから飛んできたときのparamsに格納されたidを元に、該当する投稿データを探して、変数に代入する
end
def update
@output = Output.find(params[:id])
# 編集ページの送信ボタンから飛んできたときのparamsに格納されたidを元に、該当する投稿データを探して、変数に代入する
if @output.update(output_params)
redirect_to output_path, notice: "アウトプットを編集しました"
else
flash.now[:danger] = "編集に失敗しました"
render 'edit'
end
end
編集に成功したときは、redirect_toでshowページに飛び、
編集に失敗したときは、renderでeditページへ戻る。
renderとredirect_toの違いについては、こちらの記事を参考にしてみてください!
・editページの作成
% touch app/views/outputs/edit.html.erb
・editページの編集
# app/views/outputs/edit.html.erb
<%= render 'form' %>
※formパーシャルはnewページで使用しているのと同様のものを使用します
# app/views/outputs/_form.html.erb
<%= form_with model: @output do |f|%>
<div class="field">
<%= f.label :title, "タイトル" %></br>
<%= f.text_field :title%>
</div>
<div class="field">
<%= f.label :body, "本文" %></br>
<%= f.text_area :body%>
</div>
<div class="submit">
<%= f.submit "送信"%>
</div>
<% end %>
・編集リンクの追加
# app/views/outputs/show.html.erb
<h3>タイトル</h3>
<%= @output.title %><br>
<h3>本文</h3>
<%= @output.body %><br>
<%= link_to"編集", "/outputs/#{@output.id}/edit" %> #追加
editページへ飛ぶための編集リンクを追加します!
indexページから編集完了するまでの流れはこんな感じです↓↓
・indexページの「test11」を選択してshowページに飛びます
・「編集」をクリックしてeditページへ飛びます
・editページで以下のように編集して、送信ボタンをクリックします
・このように編集が成功すると、先程のshowページへ飛んで編集後の内容に変更されています
2 削除機能の実装
・destroyアクションの追加
# app/controllers/outputs_controller.rb
def destroy
@output = Output.find(params[:id])
# 削除リンクから飛んできたときのparamsに格納されたidを元に、該当する投稿データを探して、変数に代入する
if @output.destroy
redirect_to root_path, notice: "アウトプットを削除しました"
else
flash.now[:danger] = "削除に失敗しました"
render 'show'
end
end
削除に成功したときは、redirect_toでindexページに飛び、
削除に失敗したときは、renderでshowページに飛ぶ。
・削除リンクの追加
# app/views/outputs/show.html.erb
<h3>タイトル</h3>
<%= @output.title %><br>
<h3>本文</h3>
<%= @output.body %><br>
<%= link_to"編集", "/outputs/#{@output.id}/edit" %>
<%= link_to"削除", "/outputs/#{@output.id}", method: :delete %> #追加
destroyアクションへ飛ぶための、削除リンクを追加します。
indexページから削除完了するまでの流れはこんな感じです↓↓
・「test11編集済」のリンクをクリックしてshowページへ飛びます
・削除ボタンをクリックします
・削除が成功すると、indexページへ戻り対象の投稿が削除されています
3 投稿をしたユーザーだけに編集リンクと削除リンクを表示するようにする
このままでは、投稿をしたユーザー以外、
つまり、誰もが全ての投稿を編集・削除出来てしまうという、とてもカオスな状態になってしまいます笑
そのため、投稿をしたユーザーだけが投稿編集・削除を行えるようにしていきましょう^ ^
・表示判定のif文を追加する
<h3>タイトル</h3>
<%= @output.title %><br>
<h3>本文</h3>
<%= @output.body %><br>
<% if user_signed_in? && current_user.id == @output.user_id %> #追加
<%= link_to"編集", "/outputs/#{@output.id}/edit" %>
<%= link_to"削除", "/outputs/#{@output.id}", method: :delete %>
<% end %> #追加
<% if user_signed_in? && current_user.id == @output.user_id %>
この記述、current_user.id == @output.user_idだけ書いとけばいいんじゃないの?
って思われる方もいるかと思います。実際、自分もそう思った時がありました。
でも、current_user.id == @output.user_idだと、ログインしていない時current_user.idがnilになってしまい、エラーになっていまいます。
user_signed_in?の場合は、ログインしていない時はif文自体がスキップされるのでエラーになりません。
そのため、<% if user_signed_in? && current_user.id == @output.user_id %>という書き方をしているのです。
参考記事
・今どのユーザーがログインしているか分かるようにするためのコードを追記
※確認のために追記するだけなので、実際に書かなくても問題ありません
# app/views/layouts/_header.html.erb
<% if user_signed_in? %>
<%= current_user.name%><span>がログインしています</span>
<% end %>
まずは実際の投稿者である「TEST USER」でログインして確認します。
・自分の投稿である「test10」のリンクをクリックしてshowページへ飛びます
・このように編集ボタン・削除ボタンが表示されています
次に、投稿者ではないユーザーで確認してみましょう。
・別のユーザーでログインします
・このように、編集ボタン・削除ボタンが表示されません
これで、投稿者のみに編集・削除リンクが表示されるようになりました!
これで投稿編集・削除機能(edit,update,destroy)の実装は完了です!
お疲れ様でした^ ^
最後に
今回は投稿編集・削除機能の実装方法について解説してみました!
次回は、投稿へのコメント機能実装方法について解説したいと思います!
今後も、どんどん記事投稿を行なっていくので、
よければ、応援の方お願い致します(*^ω^*)
それでは!