質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.46%
Ruby on Rails

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

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

Q&A

0回答

311閲覧

コメントをページ遷移なしでビューに追加する実装

Zengo_Master

総合スコア19

Ruby on Rails

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

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

0グッド

0クリップ

投稿2020/09/25 10:03

RailsでAjaxを用いたコメント機能

RailsでECサイトを作成しており、商品のレビュー投稿を実装しているところです。投稿した内容を、ページ遷移なしに追加するのが目的です。

調べた内容

[Rails]Ajaxを用いて非同期でコメント機能の実装
https://qiita.com/yuto_1014/items/c7d6213139a48833e21a

検証作業と結果

上記のQiitaを参考に、ファイルやコードを追加しました。
現在のコードを掲載します。

app/controllers/items_controller.rb

ruby

1class ItemsController < ApplicationController 2 before_action :set_item, only: [:edit, :show, :destroy, :update] 3 before_action :move_to_index, except: [:index, :show, :search] 4 5 def index 6 @items = Item.all.order('created_at DESC') 7 end 8 9 def new 10 @item = Item.new 11 end 12 13 def create 14 @item = Item.create(item_params) 15 if @item.valid? 16 @item.save 17 redirect_to root_path 18 else 19 render 'new' 20 end 21 end 22 23 def destroy 24 if @item.destroy 25 redirect_to root_path 26 else 27 redirect_to item_path(@item.id) 28 end 29 end 30 31 def edit 32 end 33 34 def update 35 if @item.update(item_params) 36 redirect_to item_path(@item.id) 37 else 38 render 'edit' 39 end 40 end 41 42 def show 43 @comment = Comment.new 44 @comments = @item.comments.order(created_at: :desc) 45 end 46 47 def search 48 @items = Item.search(params[:keyword]) 49 end 50 51 private 52 53 def item_params 54 params.require(:item).permit(:image, :name, :description, :category_id, :status_id, :shipping_fee_burden_id, :shipping_prefecture_id, :shipping_days_id, :price).merge(user_id: current_user.id) 55 end 56 57 def set_item 58 @item = Item.find(params[:id]) 59 end 60 61 def move_to_index 62 redirect_to action: :index unless user_signed_in? 63 end 64end

app/controllers/comments_controller.rb

ruby

1class CommentsController < ApplicationController 2 def create 3 @item = Item.find(params[:item_id]) 4 #投稿に紐づいたコメントを作成 5 @comment = @item.comments.build(comment_params) 6 @comment.user_id = current_user.id 7 @comment.save 8 render :index 9 end 10 11 def destroy 12 @comment = Comment.find(params[:id]) 13 @comment.destroy 14 render :index 15 end 16 17 private 18 def comment_params 19 params.require(:comment).permit(:content, :item_id, :user_id) 20 end 21end

app/views/items/show.html.erb

html

1<div class="whole"> 2 3 <div class="furima"> 4 <%= link_to image_tag("furima-logo-color.png", width: '200'), root_path %> 5 </div> 6 7 <div class="item-show"> 8 9 <div class="show-item-name"> 10 <%= @item.name %> 11 </div> 12 13 <div class="show-item-image"> 14 <%= image_tag @item.image.variant(resize:'300x300') %> 15 <% if Purchase.exists?(item_id: @item.id) %> 16 <div class="sold-out"> 17 <span>Sold Out!!</span> 18 </div> 19 <% end %> 20 </div> 21 22 <div class="show-item-price"> 23 <%= @item.price %>円 24 </div> 25 26 <% if user_signed_in? && current_user.id == @item.user_id %> 27 <div class="edit"> 28 <%= link_to "商品の編集", edit_item_path(@item.id), method: :get, class: "edit-btn" %> 29 </div> 30 <div> 31 <%= link_to "商品の削除", item_path(@item.id), method: :delete, class: "destroy-btn" %> 32 </div> 33 <% elsif user_signed_in? && current_user.id != @item.user_id && Purchase.exists?(item_id: @item.id) == false %> 34 <div> 35 <%= link_to "購入画面に進む", item_purchases_path(@item.id), method: :get, class: "purchase-btn" %> 36 </div> 37 <% end %> 38 39 <div class="item-description-box"> 40 <span><%= @item.description %></span> 41 </div> 42 43 <div class="item-table"> 44 <table border="1" style="border-collapse: collapse"> 45 <tr> 46 <th>出品者</th> 47 <td><%= @item.user.nickname %></td> 48 </tr> 49 <tr> 50 <th>カテゴリー</th> 51 <td><%= @item.category.name %></td> 52 </tr> 53 <tr> 54 <th>商品の状態</th> 55 <td><%= @item.status.name %></td> 56 </tr> 57 <tr> 58 <th>配送料の負担</th> 59 <td><%= @item.shipping_fee_burden.name %></td> 60 </tr> 61 <tr> 62 <th>発送元の地域</th> 63 <td><%= @item.shipping_prefecture.name %></td> 64 </tr> 65 <tr> 66 <th>発送日の目安</th> 67 <td><%= @item.shipping_days.name %></td> 68 </tr> 69 </table> 70 </div> 71 72 <div class="review-contents"> 73 74 <div class="row"> 75 <p class="text-left title"><レビュー></p> 76 <ul> 77 <li id="comments_area"> 78 <%= render partial: 'comments/index', locals: { comments: @comments } %> 79 </li> 80 </ul> 81 <hr> 82 <% if user_signed_in? %> 83 <div class="comment-create"> 84 <h3 class="text-left">レビューを投稿する</h3> 85 <%= render partial: 'comments/form', locals: { comment: @comment, item: @item } %> 86 </div> 87 <% end %> 88 </div> 89 90 </div> 91 92 </div> 93 94 <div class="furima"> 95 <%= link_to image_tag("furima-logo-color.png", width: '200'), root_path %> 96 </div> 97 98</div>

以下は、表示内容ですが、Qiitaのコードから、投稿者のアバター画像を削っています。
app/views/comments/_index.html.erb

html

1<!-- コメント内容(2件) ------------------------------------------------------------------> 2<%= comments.count %>件のコメント 3<h6 class="more" data-toggle="collapse" data-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample">もっと見る....</h6> 4<% comments.first(2).each do |comment| %> 5 <% unless comment.id.nil? %> 6 <li class="comment-container"> 7 <div class="comment-box"> 8 <div class="comment-text"> 9 <div class="comment-entry"> 10 <%= comment.content %> 11 <% if comment.user == current_user %> 12 <%= link_to item_comment_path(comment.item_id, comment.id), method: :delete, remote: true, class: "comment_destroy" do %> 13 <i class="fas fa-trash" style="color: black;"></i> 14 <% end %> 15 <% end %> 16 </div> 17 <span class="comment-date pull-right"> 18 <%= comment.created_at.strftime('%Y/%m/%d %H:%M:%S') %> 19 </span> 20 </div> 21 </div> 22 </li> 23 <% end %> 24<% end %> 25<!-- コメント内容(3件目以降) ------------------------------------------------------------------> 26<div class="collapse" id="collapseExample"> 27 <% comments.offset(2).each do |comment| %> 28 <% unless comment.id.nil? %> 29 <li class="comment-container"> 30 <div class="comment-box"> 31 <div class="comment-text"> 32 <div class="comment-entry"> 33 <%= comment.content %> 34 <% if comment.user == current_user %> 35 <%= link_to item_comment_path(comment.item_id, comment.id), method: :delete, remote: true, class: "comment_destroy" do %> 36 <i class="fas fa-trash" style="color: black;"></i> 37 <% end %> 38 <% end %> 39 </div> 40 <span class="comment-date pull-right"> 41 <%= comment.created_at.strftime('%Y/%m/%d %H:%M:%S') %> 42 </span> 43 </div> 44 </div> 45 </li> 46 <% end %> 47 <% end %> 48</div>

app/views/comments/_form.html.erb

html

1<!-- コメント入力フォーム ------------------------------------------------------------> 2<%= form_with(model: [item, comment], url: item_comments_path(@item) ) do |f| %> 3 <%= f.text_area :content, class: "input-mysize" %><br> 4 <%= f.submit "送信", class: "btn btn-outline-dark comment-submit float-right" %> 5<% end %>

app/views/comments/index.js

js

1$("#comments_area").html("<%= j(render 'index', { comments: @comment.item.comments }) %>") 2$("textarea").val('')

しかし、ブラウザで試すと、以下の問題が発生しました。

・「送信ボタン」を押してもビューに反映されない(非同期処理の失敗)が、ページをリロードすれば反映される。
・2件だけ表示されるはずが、リロードするたびに全てのコメントが表示されている。

エラー文が出ていないので、原因の解明に詰まっています。なぜ、以上の問題が起きてしまうのでしょうか?原因と解決案を教えていただきたいです。

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

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

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

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

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

no1knows

2020/09/25 17:27

「[Rails]Ajaxを用いて非同期でコメント機能の実装」の実装を見る限り、非同期通信ができないような気がしますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問