🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Q&A

解決済

2回答

691閲覧

JavaScriptを使用してコメントを非同期通信で表示したいが、初めのコメントのみjsonが表示されてしまう。

magatamaamagata

総合スコア4

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

0グッド

0クリップ

投稿2020/11/28 10:07

編集2020/11/29 02:43

現状

コメントを非同期通信で表示できるようにしました。
しかし初めのコメントのみcreateアクションのURIに飛びjson形式のparamsが表示されてしまいます。
skill/showは投稿を表示しているページでそこでcommentが非同期でできるようにしています。
skill/showページをリロードすると写真のように表示されているjsonのコメントが表示されます。それ以降は非同期でコメントを表示することができます。

skill_comments POST /skills/:skill_id/comments(.:format) comments#create

イメージ説明

####コード

html:skill/show.html.erb

1<body> 2<%= require "json"%> 3 <div id="list"></div> 4 <% @comments.each do |comment| %> 5 <%if comment.skill_id == @skill.id %> 6 <div id="getid" class= "comment-area" data-skillid=<%= comment.skill.id %> > 7 <div class="comment-date"> 8 <time datetime="<%= comment.created_at %>"> 9 <%= time_ago_in_words(comment.created_at) %>前 10 </time> 11 </div> 12 <div class="comment-content"> 13 <%= comment.text %> by <%= comment.user.nickname%> 14 </div> 15 </div> 16 <% end %> 17 <% end %> 18 </div> 19</div> 20</div> 21 <% if user_signed_in? && current_user.id == @skill.user.id %> 22 <div class="edit-delete-btn"> 23 <%= link_to '編集', edit_skill_path(params[:id]), method: :get, class: "skill-edit-btn" %> 24 <%= link_to '削除', skill_path(params[:id]), method: :delete, class:'skill-destroy-btn' %> 25 </div> 26 <% end %> 27</body> 28 29<%# 非同期通信をする時に使用 %> 30<script> 31 32function comment() { 33 const submit = document.getElementById("submit"); 34 submit.addEventListener("click", (e) => { 35 const formData = new FormData(document.getElementById("form")); 36 console.log(formData); 37 const XHR = new XMLHttpRequest(); 38 const post = document.getElementById("getid"); 39 const skillId = post.getAttribute("data-skillId"); 40 XHR.open("POST", `/skills/${skillId}/comments`, true); 41 XHR.responseType = "json"; 42 XHR.send(formData); 43 XHR.onload = () => { 44 if (XHR.status != 200) { 45 alert(`Error ${XHR.status}: ${XHR.statusText}`); 46 return null; 47 } 48 const item = XHR.response.comment; 49 console.log(item) 50 const list = document.getElementById("list"); 51 console.log(list); 52 const formText = document.getElementById("comment"); 53 const HTML = ` 54 <div class="comment" data-id=${item.id}> 55 <div class="post-date"> 56 投稿日時:${item.created_at} 57 </div> 58 <div class="post-comment"> 59 ${item.text} 60 </div> 61 </div>`; 62 list.insertAdjacentHTML("afterend", HTML); 63 formText.value = ""; 64 }; 65 e.preventDefault(); 66 }); 67} 68window.addEventListener("load", comment); 69</script>

ruby:comments_controller

1class CommentsController < ApplicationController 2 before_action :authenticate_user! 3 4 def new 5 @comment = Comment.new 6 @skill = Skill.find(params[:skill_id]) 7 end 8 9 def create 10 @skill = Skill.find(params[:skill_id]) 11 comment = Comment.create(comment_params) 12 render json: { comment: comment } 13 end 14 15 private 16 17 def move_to_index 18 @skill = Skill.find(params[:skill_id]) 19 redirect_to root_path unless user_signed_in? && (current_user.id == @skill.user.id) 20 end 21 22 def comment_params 23 @skill = Skill.find(params[:skill_id]) 24 params.require(:comment).permit(:text).merge(user_id: current_user.id, skill_id: @skill.id) 25 end 26end

わかったこと

####1

73行目: XHR.open("POST", `/skills/${skillId}/comments`, true);

このtrueがfalseだと上記のようにjsonファイルが表示されるということ。

####2
commentのcreateアクションのrender json: { comment: comment }の直後でbinding.pryをするとskill/showのビューに止まっており、<script>の1行目にdebugger;と書いても止まらずjsonファイルが表示されてしまうため、どこでこの表示が支持されているのかわかりません。

####3
turbolinksが悪さをしているのかなとも思い、skill/showページに来る前のform_withにもコメントを送信するform_withにもdata: {"turbolinks" => false}と記述しました。

解決したいこと

コメントがまだない状態でも非同期通信でコメントを表示させたいです。
よろしくお願いいたします。

追加で分かったこと

https://pikawaka.com/rails/json
ここにある通り、render jsonとするとjsonがviewに表示されるみたいです。
JavaScriptのjsonの読み込みがおかしいのかなと思います。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

no1knows

2020/11/29 22:54

> コメントがまだない状態でも非同期通信でコメントを表示させたいです。 とはどういう意味でしょうか? また実装したいのは、コメントを非同期で投稿・表示したいということでしょうか?
magatamaamagata

2020/11/30 07:07

実装したいのは、コメントを非同期で投稿・表示したいということです。 > コメントがまだない状態でも非同期通信でコメントを表示させたいです →投稿にコメントが0個の時にコメントフォームを送信すると、JSONがビューに表示されてしまう。そこで先ほどのページに戻り更新をするとメッセージは投稿されており、その状態で次のメッセージを送信するとうまく非同期で投稿できる、という意味でございます。 わかりにくくて申し訳ありません。
guest

回答2

0

ベストアンサー

直接的な回答でなくて恐縮ですが・・・
Railsで非同期の投稿+表示を実装する場合、remote: trueを利用するのが一般的です。

Railsのやり方を学ぶのであれば、まずはscaffoldを利用して下記の動作確認してみると良いかと思います。
※投稿+コメントの例ではなくてすいません。
※form_withの場合、remote: trueがデフォルトとなっており、下記例では省略されています。

Railsガイド:4.1 シンプルな例

投稿2020/11/30 09:36

no1knows

総合スコア3365

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

render json: { comment: comment }

render json: { comment: comment.text }

投稿2020/11/28 21:55

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

magatamaamagata

2020/11/29 02:15

ご回答ありがとうございます。 確かにrender json: { comment: comment }だとコメント以外の情報も含まれており受け取れないのかなとも思ったのですが、 実践してみたところ質問文画像のように{"comment":"hogehoge"}と表示されるだけでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問