初めに
非同期通信でのコメント機能は実装ずみで、「401字以上のコメント」はNGというバリデーションは、 かけていたものの、エラーメッセージが出るようにしていませんでした・・・。 少し実装に苦労はしたものの、非同期通信への理解が深まったのでまとめていきます!!バリデーションをかけておく
class PostComment < ApplicationRecord
default_scope -> { order(created_at: :desc) }
# あるコメントに紐づくユーザーも記事も1
belongs_to :user
belongs_to :post
validates :comment, presence: true, length: { maximum: 400 }
end
一応マイグレーションファイルも。
class CreatePostComments < ActiveRecord::Migration[5.2]
def change
create_table :post_comments do |t|
t.text :comment, null: false
t.integer :user_id,null: false
t.integer :post_id,null: false
t.timestamps
end
end
end
<%= form_with(model:[post, post_comment], remote: true) do |f| %>
<%= f.text_area :comment, rows:'2',placeholder: "感想や疑問点をコメントで伝えましょう",required: true,class:"form-control" %>
<%=f.submit "コメントする",class:"mt-2 btn btn-outline-secondary btn-block btn-sm"%>
とりあえず、ここまでやると空欄での投稿に対しては以下のように出てきます。
ただ、401文字打ってもバリデーションには引っかかるものの何も出てこないという状況です。
コントローラーで保存できなかった場合の記述を書く!
def create
post = Post.find(params[:post_id])
@comment = current_user.post_comments.new(post_comment_params)
@comment.post_id = post.id
@post = Post.find(params[:post_id])
if @comment.save
# ユーザーステータス無効で、投稿者とコメント者が等しいとき
if current_user != @post.user && @post.user.is_valid == true
@post.create_notification_by(current_user)
end
@post_comment = PostComment.new
else
render 'error'
end
end
通知機能も実装してるのでわかりにくくなっているかもしれません・・・・すみません。
コメントがバリデーションに引っかかってしまい保存されなかったら、
render 'error'
というところがポイントです!!!
さてrender先にいきます。
error.js.erb
$("#comments-error").html("<%= j(render 'layouts/errors', obj: @comment) %>");
コメントが401字でバリデーションに引っかかってるので、@commentの持ってる値としては
”false"になっています。
そしてここの記述としては、idがcomments-error
となっているどこかに、
<%= j(render 'layouts/errors', obj: @comment) %>
を渡すという意味
です。
ちなみに'layouts/errors'の中身はこんな感じになっています。
<% if obj.errors.any?%>
<div class="text-center" style="color:red;">
<%=obj.errors.count %>件のエラーが発生しました。<br>
<% obj.errors.full_messages.each do |message| %>
<%= message %>
<% end %>
</div>
<% end %>
さてこのエラー文を差し込む、id = comments-error
の箇所を作りましょう。
エラーメッセージを出す
#ここです!!!!
<div id ="comments-error"></div>
<%= form_with(model:[post, post_comment], remote: true) do |f| %>
<%= f.text_area :comment, rows:'2',placeholder: "感想や疑問点をコメントで伝えましょう",required: true,class:"form-control" %>
<%=f.submit "コメントする",class:"mt-2 btn btn-outline-secondary btn-block btn-sm"%>
<% end %>
<div id ="comments-error"></div>
という箇所を作成しました。
これでコメント欄のすぐ上にエラーメッセージができます。
まとめ:非同期通信のエラーメッセージの流れ
コメントがバリデーションに引っ掛かり保存されない
↓
errorのjsファイルに飛ぶ
↓
jsファイルは指定されてるidに、html以下を差し込む
↓
該当のidが記載されてる箇所で、html以下を受け取り表示する。
要するに、普段は
<div id ="comments-error"></div>なってるところが、
<div id ="comments-error">render 'layouts/errors', obj: @comment</div>
になってくれて、エラー文が出てくると!
そもそも非同期通信とは..
最後に書くことはでなはいですが、簡単にまとめていきます。 簡単にいうと「データを送信したら、もう画面を書き換えてもらう」ということです。 サーバーからの結果は待ちません。 通常であればちゃんと応答待ちますが、非同期通信は待ちません! メリットとしては待つ必要が無いから、早いということです。 サーバーが処理してる間に、操作ができます。 「あとやっといて〜」って感じでしょうか。最後に
非同期通信がうまくいかないときって、大体スペルミスのような気がしますので、
スペルミスにご注意ください!!!!!!