4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

駆け出しエンジニアの第一歩!Advent Calendar 2020

Day 19

【Rails】コメント機能のエラーメッセージ表示方法(初学者向け)

Posted at

はじめに

本記事は、駆け出しエンジニアの第一歩!AdventCalendar2020 19日目の記事です。

アプリケーション概要

ユーザー投稿に対して、コメントができる一般的なアプリケーションです。(ユーザー登録はdeviseを使用)
現状では、commentに対するバリデーションは設定していないため、空投稿が可能な状態になっています。

ER図

_2020-12-15_12.07.40.png

コメント機能

実装前のコメント機能のviewとcontrollerは以下の通りです。

post_images/show.html.erb ※コメント投稿部分のみ抜粋
<%= form_with model:[@post_image, @comment], local:true do |f| %>
  <div class="row">
    <div class="col-sm-12">
       <%= f.text_area :comment, rows:'5', class: "form-control",placeholder: "コメントをここに" %>
    </div>
  </div>
   <%= f.submit "送信する", class: "btn btn-lg btn-base-1 mt-20 pull-right" %>
<% end %>
post_images/controller.rb
def show
    @post_image = PostImage.find(params[:id])
    @comment = Comment.new
end

comments/controller.rb
def create
   post_image = PostImage.find(params[:post_image_id])
   comment = current_user.comments.new(comment_params)
   comment.post_image_id = post_image.id
   comment.save
   redirect_to post_image_path(post_image)
end

private
def comment_params
  params.require(:comment).permit(:comment)
end

コメント機能にエラーメッセージをつける

1. コメントモデルのバリデーション設定

models/comments.rb
validates :comment, presence: true

2. コントローラを条件分岐させる

ローカル変数commentのsaveに失敗した場合、commentはエラー内容を含んだものであるとわかる。その状態をviewに反映させる(エラーメッセージ を表示する)ために、インスタンス変数@error_commentにエラー内容を含んだcommentを再定義する必要がある。

comments/controller.rb
def create
    post_image = PostImage.find(params[:post_image_id])
    comment = current_user.post_comments.new(comment_params)
    comment.post_image_id = post_image.id

   #6行追加(if〜end)--------------------------------
    if comment.save
	    redirect_to post_image_path(post_image)
	else
		@error_comment = comment
		render 'post_image/show'
	end
   #-----------------------------------------------
end

private
def comment_params
  params.require(:comment).permit(:comment)
end

3. エラーメッセージの表示を記載する

さっき再定義した@error_commentをviewに渡す。

post_images/show.html.erb ※コメント投稿部分のみ抜粋
<%= form_with model:[@post_image, @post_comment], local:true do |f| %>

----エラーメッセージの表示を追加------------------------------------------------
  <% if @error_comment.present? %>
    <div id="error_explanation">
      <h2><%= @error_comment.errors.count %>件のエラーが発生しました。</h2>
      <ul>
        <% @error_comment.errors.full_messages.each do |message| %>
        <li><%= message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
--------------------------------------------------------------------------

  <div class="row">
    <div class="col-sm-12">
      <%= f.text_area :comment, rows:'5', class: "form-control",placeholder: "コメントをここに" %>
    </div>
  </div>
  <%= f.submit "送信する", class: "btn btn-lg btn-base-1 mt-20 pull-right" %>
  <% end %>

2行目の<% if @error_comment.present? %>でエラーがあるときのみ、表示されるようにする。@error_commentは、commentが空の投稿の時のみ再定義される変数のため、showページを表示するときには定義されていない。
<% if @error_comment.present? %>がないと以下のようなエラーが出る。
_2020-12-15_15.06.32.png

4. post_imageのshowアクションの内容をcreateアクションに追記する

コメント投稿が失敗した場合、post_imageのshowページへrenderするようにしてあるが、showのviewを表示するのに必要なインスタンス変数がcommentコントローラのcreateアクションにはないので、追記してやる必要がある。

post_images/controller.rb
def show
    @post_image = PostImage.find(params[:id])
    @post_comment = PostComment.new
end

追記する。

comments/controller.rb
def create
    post_image = PostImage.find(params[:post_image_id])
    comment = current_user.post_comments.new(post_comment_params)
    comment.post_image_id = post_image.id
    if comment.save
	    redirect_to post_image_path(post_image)
	else
		@error_comment = comment

#------post_imageのshowアクションを追加---------------
		@post_image = PostImage.find(params[:id])
	    @post_comment = PostComment.new
#-------------------------------------------------
		render 'post_image/show'
	end
end

private
def comment_params
  params.require(:comment).permit(:comment)
end

これでコメント投稿を実行しても、idがないので見つけることができないという以下のようなメッセージが出る。正確にはidはあるけど名称が変わって違うものになっているのでidを見つけることができないという感じ。_2020-12-15_15.19.57.png
rails routesで確認すると、

Prefix Verb URI Pattern Controller#Action
post_image GET /post_images/:id(.:format) post_image#show
post_image_comments POST /post_images/:post_image_id/comments(.:format) comment#create
showアクションではpost_imagesのパラメーターidは:idであったが、createアクションの場合、パラメーターidはpost_image_idとなっている。そのため、パラメーターidをpost_image_idに変更する。
comments/controller.rb
def create
    post_image = PostImage.find(params[:post_image_id])
    comment = current_user.post_comments.new(post_comment_params)
    comment.post_image_id = post_image.id
    if comment.save
	    redirect_to post_image_path(post_image)
	else
		@error_comment = comment
 #----------変更(:id → :post_image_id)------------------------
		@post_image = PostImage.find(params[:post_image_id])
 #------------------------------------------------------------
	    @post_comment = PostComment.new
		render 'post_image/show'
	end
end

private
def comment_params
  params.require(:comment).permit(:comment)
end

_2020-12-15_15.37.08.png

まとめ

非常に回りくどい説明になりましたが、初学者の方でエラー解決に苦労している方などの参考になれば幸いです。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?