前回の作業で編集フォームと一覧表示が作成できました。
今回は削除機能を追加していきます。
目次
destroyアクションの追加
config/routes.rb
Rails.application.routes.draw do
root to: "memo#index"
resources :memo, only: [:new, :create, :edit, :update, :destroy]
end
resourcesにdestroyアクションを追加

memo#destroyが追加されました。
ポイント
このようにroutes.rbを編集するとルーティングが生成され、機能への道筋を確保できるので機能追加時は忘れないうちにroutes.rbを編集した方がいいと思っています。
controllerにdestroyアクション追加
app/controllers/memo_controller
def destroy
post = Post.find(params[:id])
post.destroy
redirect_to root_path
end
updateとほぼ同じです。
1行目でレコードを指定
2行目で削除
3行目でトップページへ遷移
ビューページの作成
ビューの作成と行ってもeditの時と同じで削除機能のリンクを貼るだけです。
app/views/memo/index.html.erb
<h1>Memo app</h1>
<% @posts.each do |post| %>
<ul>
<li>
<%= post.content %>
<%= link_to "編集", edit_memo_path(post) %>
<%= link_to "削除", memo_path(post.id), method: :delete %>
</li>
</ul>
<% end %>
<%= link_to '新規投稿', '/memo/new' %>
ここで注目したいのがPrefixとmethodです。Prefix:memo_path(post.id)はルーティングを確認していただくとわかりますがupdateと同じなんです。



僕は最初わからずPrefixではなく、Path(/memo/:id)使っていました。(汗
ポイント
method:method: :delete
ここでmethodを指定するとdestroyアクションが起動します。
ブラウザで確認すると削除機能が使えるようになりました。
リファクタリング
機能実装がある程度終わったら可読性を上げるために同じような記述をひとまとめにしていきます。
app/controllers/memo_controller.rb
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
@post.update(post_params)
redirect_to root_path
end
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to root_path
end
@post = Post.find(params[:id])この記述が3つあるのがわかります。こちらをひとまとめにしていきます。
private以下にset_postメソッドを追加します。
def set_post
@post = Post.find(params[:id])
end
before_actionを2行目あたりに追加します。
ポイント
before_action
すでに定義されている各アクションの実行前に作動してくれる。
class MemoController < ApplicationController
before_action :set_post, only: [:edit, :update, :destroy]
def index
@posts = Post.all
end
def new
end
def create
Post.create(post_params)
redirect_to root_path
end
def edit
end
def update
@post.update(post_params)
redirect_to root_path
end
def destroy
@post.destroy
redirect_to root_path
end
private
def post_params
params.permit(:content)
end
def set_post
@post = Post.find(params[:id])
end
end
これで投稿した文を削除することができるようになりました。
エラーハンドリング
エラーハンドリング とはエラーが発生した時のアクションを決める事です。
例えば、今回の投稿機能に空文字不可を追加してみます。
バリデーションをかける
app/models/memo.rb
class Post < ApplicationRecord
validates :content, {presence: true}
end
validatesはバリデーションと言って制約をかける事です。presence: trueをつける事で、存在している事!となります。
要約するとPostテーブルのcontentカラムには空で保存できない
実際にから文字を投稿指定見ると保存はできなくなりましたが、なぜ保存できなかったのかわかりません。
エラーハンドリング をする(create)
app/controllers/memo_controller.rb
def create
@post = Post.create(post_params)
if @post.save
flash[:notice] = "投稿できました"
redirect_to root_path
else
flash[:alert] = "文字を入力してください"
redirect_to new_memo_path
end
end
createの部分をif文を使い、条件分岐します。saveできたらフラッシュメッセージ(投稿できました)を表示させトップページへ戻す
できなかったら(文字を入力してください)を表示させ新規投稿ページへ留める。
フラッシュメッセージの表示箇所の指定
app/views/layouts/application.erb
<body>
<%= flash[:notice] %>
<%= flash[:alert] %>
<%= yield %>
</body>
<%= yield %>より上に書くことで、各ページの上部に表示させることができます。実際に見てみましょう。

投稿成功

投稿失敗
こんな感じで投稿が成功したか、失敗したかがわかるようになりました。アラートっぽくするために、CSSを当ててみます。
app/views/layouts/application.erb
<body>
<div class="notification">
<div class="notice"><%= flash[:notice] %></div>
<div class="alert"><%= flash[:alert] %></div>
</div>
<%= yield %>
</body>
app/assets/stylesheets/memo.scss
.notification {
.notice {
background-color: blue;
color: white;
text-align: center;
}
.alert {
background-color: orange;
color: white;
text-align: center;
}
}
もう一度投稿を試すと、フラッシュに修飾されていることがわかります。
同じ要領でupdate(更新)もエラーハンドリング します。
エラーハンドリング をする(update)
app/controllers/memo_controller.rb
def update
if @post.update(post_params)
flash[:notice] = "投稿できました"
redirect_to root_path
else
flash[:alert] = "文字を入力してください"
redirect_to edit_memo_path(@post.id)
end
end
pathの指定
editなどurlにidが必要なページには引数を入れてあげれば大丈夫です。例えば (http://localhost:3000/memo/5/edit)にredirectさせるためにはPlefixのmemo_pathにidを渡すのでredirect_to edit_memo_path(@post.id)そして@postにはアップデートしたレコードが代入されているので、idだけを取り出し引数としました。
このまま削除もエラーハンドリング します。
エラーハンドリング する(delete)
app/controllers/memo_controller.rb
def destroy
if @post.destroy
flash[:delete] = "削除しました"
redirect_to root_path
else
redirect_to root_path
end
end
app/assets/stylesheets/memo.scss
.notification {
.notice {
background-color:blue;
color: white;
text-align: center;
}
.alert {
background-color: orange;
color: white;
text-align: center;
}
.delete {
background-color: red;
color: white;
text-align: center;
}
}
以上でエラーハンドリング は終了です。


メモ
何か処理を行う時に成功した場合と失敗した場合を書いておかないと、実際に使用した時にエラー画面が表示されてしまう事になります。

プログラミングを学んでいない人が入力ミスでこんなエラー画面が出てきてしまったらびっくりしてしまうと思います。
ユーザビリティ向上していくことでより良いWEBアプリになっていくと思うので丁寧にエラーハンドリング して行きます。
ここまで読んでいただき、ありがとうございました。
おかしなコードがありましたらコメントしていただけると助かります。