#はじめに
Rails 6.0.3.4
コメント機能のエラーハンドリングの実装中躓いたのでここに記録します。
レシピ投稿サイトを作っており、レシピの詳細に入ると、その中にコメント機能とコメント一覧がある状態です。
コメントを投稿したユーザーの名前も一緒に載せます。
Commentモデル・コントローラー・コメントを表示させるビューは出来上がっているものとします。
ルーティングでは、CommentはRecipeにネストしてあります。
#バリデーションを作成
class Comment < ApplicationRecord
belongs_to :recipe
belongs_to :user
validates :contents, presence: true, length: { maximum: 100 }
end
このような感じです。
contentsはコメント内容が入るカラム名です。
contentsのバリデーションは、空欄では投稿できないことと、100文字以内であるというものにしました。
#commentsコントローラーの編集
class CommentsController < ApplicationController
def create
@recipe = Recipe.find(params[:recipe_id]) #どのレシピと紐づいているか定義
@comment = Comment.new(comment_params) #空のインスタンスを作る(ストロングパラメータも忘れずに)
if @comment.save #もしコメントがセーブできたら
redirect_to recipe_path(@comment.recipe.id) #レシピ一覧に戻ります。戻り先のパスに、どのレシピのidなのかを教えてあげましょう。アソシエーションしているので、@comment.recipe.idでOK
else #もし保存できなかったら(バリデーションで弾かれた時)
@comments = @recipe.comments.includes(:user) #コメントは今までのコメントを表示させておき(ここを書いてなかった)
render 'recipes/show' #レシピ一覧へ戻ります
end
end
private
def comment_params
略
end
end
※recipesコントローラーの記述は省略しますが、
recipeビューでうつしたいものなのでもちろん空のインスタンスを置いてあげ、
eachメソッドでコメントが回せるように@comments = で、そのレシピに対して投稿された保存済みのコメント定義してあげます
私はとりあえず、保存されない時はrenderで戻せばいいや!とrenderしか書いていませんでした。
ですがそうするとエラーメッセージは出るのですが、今までのコメントが一覧から消えてしまうエラーが起こります。
renderはそもそも直接ビューを表示させるものです。コントローラーを経由していません。
つまり、@commentsの定義がされないままrender 'recipes/show'にいってしまうので、
レシピ一覧(recipes/showのビュー)で書かれている@commentsとはなんですか?となっていたみたいです。
なのでrenderでビューに戻す前に、@commentsを定義してあげましょう。
#ビュー
念のため置いておきます。
<div class="comment-box">
<% if @comments %>
<% @comments.each do |comment| %>←ここの@commentsのこと
<p>
<strong><%= comment.user.nickname %>:</strong>
<%= comment.contents %>
</p>
<% end %>
<% end %>
</div>