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

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

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

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

517閲覧

イイねボタン非同期処理(rails)

kokotaro

総合スコア22

Ruby on Rails

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2019/05/06 22:31

編集2019/05/06 22:50

イイねボタンの非同期処理(rails)

はじめまして。
商品投稿アプリ作成中で商品詳細画面にてイイネボタンを実装に挑戦しました。
progateを参考にしながら非同期なしでのイイねボタンは実装できました。イイねハートが赤になり数がカウントされるとこまでできました。

イイネボタンを押すたびに画面全部が更新されてしまうので、イイねボタンのみ非同期処理で更新させたいと思い、
検索してトップの方に出てくる記事等を参考に、remote:trueを使うやり方でコードを書いてみましたがイイねボタンを押すとページの一番上に戻ってイイねカウントが増えるだけで(ページ全部更新されてる?)非同期処理が実行されずに困っています。
どこの箇所がおかしい等のご指摘をいただけたら助かります。

また学習開始して間もなく理解が浅いのも実感しています。
非同期処理の実装についてのオススメの記事や技術書等も可能な範囲で教えてもらえると助かります。

環境rails.5.2.3

該当のソースコード

ruby

1ルーティング 2Rails.application.routes.draw do 3 post "likes/:product_id/create" => "likes#create", as: 'like' 4 post "likes/:product_id/destroy" => "likes#destroy", as: 'unlike' 5end
コントローラー class LikesController < ApplicationController before_action :set_variables def create @like = Like.new(user_id: session[:user_id], product_id: params[:product_id]) @like.save @likes_count = Product.find_by(id: params[:product_id]) redirect_to @product end def destroy @like = Like.find_by(user_id: session[:user_id], product_id: params[:product_id]) @like.destroy redirect_to @product end def set_variables @product = Product.find(params[:product_id]) @id_name = "#like-link-#{@product.id}" end end
ビュー main.html.haml .product-detail__item__button-box__left = render 'products/product-detail/like', locals: {product: @product}
部分テンプレート likes/_like.html.haml %button.product-detail__item__button-box__left__good %span.product-detail__item__button-box__left__good__text{id: "like-link-#{@products.id}"} - if Like.find_by( user_id: current_user.id, product_id: @products.id) %i.fas.fa-heart.product-detail__item__button-box__left__good__text__heart = link_to("いいね!", unlike_path(@products.id), method: :post, remote: true) - else %i.far.fa-heart.product-detail__item__button-box__left__good__icon = link_to("いいね!", like_path(@products.id), method: :post, remote: true) %span.product-detail__item__button-box__left__good__count = @products.likes_count
views/likes/create.js.erb $("<%= @id_name %>").html('<%= escape_javascript(render("products/product-detail/like", product: @product )) %>');
views/likes/destroy.js.erb $("<%= @id_name %>").html('<%= escape_javascript(render("products/product-detail/like", product: @product )) %>');

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

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

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

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

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

odyu

2019/05/08 02:30

動きだけから判断すると、いいねボタンクリック後にURLに`#`が入っていますか?
kokotaro

2019/05/12 08:52

お返事遅くなりすいません。 クリック後URLには"#"は入ってませんでした。
odyu

2019/05/13 01:19

turbolinks使っていますか? 試しに = link_to("いいね!", unlike_path(@products.id), method: :post, remote: true) を = link_to("いいね!", unlike_path(@products.id), method: :post, remote: true, turbolinks: false) にしてみるとどうでしょうか? scrollを操作する機能が入っているようです。 https://github.com/turbolinks/turbolinks/blob/master/src/scroll_manager.ts
kokotaro

2019/05/13 02:48

turbolinks: false記述してみましたが、特に変化無しでした。 ~~~js.erbファイルが読み込めてないような気がしてきて、 上記のjs.erbファイルに $(function(){ console.log(1) }); と記述してみたのですがconsole上には何も表示されませんでした。
odyu

2019/05/13 02:54

一定の操作を行った際のrailsのログを転記してもらうことは可能でしょうか> できれば、画面表示から、いいねON、いいねOFFといった感じのログを見てみたいです。
kokotaro

2019/05/13 03:09

js.erbのrenderのパスが間違ってたので"likes/like"に変更しました。 ログはこういうもので大丈夫でしょうか? ※いいねoff Started POST "/likes/10/destroy" for ::1 at 2019-05-13 12:02:49 +0900 Processing by LikesController#destroy as JS Parameters: {"product_id"=>"10"} Product Load (0.5ms) SELECT `products`.* FROM `products` WHERE `products`.`id` = 10 LIMIT 1 ↳ app/controllers/likes_controller.rb:17 Like Load (0.4ms) SELECT `likes`.* FROM `likes` WHERE `likes`.`user_id` = 2 AND `likes`.`product_id` = 10 LIMIT 1 ↳ app/controllers/likes_controller.rb:10 (0.2ms) BEGIN ↳ app/controllers/likes_controller.rb:11 Like Destroy (0.7ms) DELETE FROM `likes` WHERE `likes`.`id` = 50 ↳ app/controllers/likes_controller.rb:11 Product Load (0.4ms) SELECT `products`.* FROM `products` WHERE `products`.`id` = 10 LIMIT 1 ↳ app/controllers/likes_controller.rb:11 Product Update All (79.7ms) UPDATE `products` SET `likes_count` = COALESCE(`likes_count`, 0) - 1 WHERE `products`.`id` = 10 ↳ app/controllers/likes_controller.rb:11 (0.7ms) COMMIT ↳ app/controllers/likes_controller.rb:11 Redirected to http://localhost:3000/products/10 Completed 200 OK in 93ms (ActiveRecord: 82.4ms) Started GET "/products/10" for ::1 at 2019-05-13 12:02:49 +0900 Processing by ProductsController#show as HTML Parameters: {"id"=>"10"} User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 ↳ app/controllers/products_controller.rb:9 Product Load (0.3ms) SELECT `products`.* FROM `products` WHERE `products`.`id` = 10 LIMIT 1 ↳ app/controllers/products_controller.rb:10 (0.3ms) SELECT `images`.`image` FROM `images` WHERE `images`.`product_id` = 10 ↳ app/controllers/products_controller.rb:11 Rendering products/show.html.haml within layouts/application Rendered products/_news.html.haml (5.4ms) Rendered products/_news.html.haml (0.5ms) Rendered products/_header.html.haml (35.8ms) User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 ↳ app/helpers/application_helper.rb:3 Like Load (0.4ms) SELECT `likes`.* FROM `likes` WHERE `likes`.`user_id` = 2 AND `likes`.`product_id` = 10 LIMIT 1 ↳ app/views/likes/_like.html.haml:3 Rendered likes/_like.html.haml (7.1ms) Rendered products/product-detail/_main.html.haml (28.2ms) Rendered products/product-detail/_comments.html.haml (19.0ms) Rendered products/product-detail/_media.html.haml (4.3ms) Rendered products/product-detail/_others.html.haml (38.4ms) Rendered products/_footer.html.haml (19.6ms) Rendered products/show.html.haml within layouts/application (163.9ms) Completed 200 OK in 228ms (Views: 217.9ms | ActiveRecord: 1.9ms) ※いいねon Started POST "/likes/10/create" for ::1 at 2019-05-13 12:05:52 +0900 Processing by LikesController#create as JS Parameters: {"product_id"=>"10"} Product Load (1.2ms) SELECT `products`.* FROM `products` WHERE `products`.`id` = 10 LIMIT 1 ↳ app/controllers/likes_controller.rb:17 (0.2ms) BEGIN ↳ app/controllers/likes_controller.rb:4 User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 ↳ app/controllers/likes_controller.rb:4 Product Load (0.3ms) SELECT `products`.* FROM `products` WHERE `products`.`id` = 10 LIMIT 1 ↳ app/controllers/likes_controller.rb:4 Like Create (0.3ms) INSERT INTO `likes` (`user_id`, `product_id`) VALUES (2, 10) ↳ app/controllers/likes_controller.rb:4 Product Update All (0.3ms) UPDATE `products` SET `likes_count` = COALESCE(`likes_count`, 0) + 1 WHERE `products`.`id` = 10 ↳ app/controllers/likes_controller.rb:4 (0.6ms) COMMIT ↳ app/controllers/likes_controller.rb:4 Redirected to http://localhost:3000/products/10 Completed 200 OK in 13ms (ActiveRecord: 3.2ms) Started GET "/products/10" for ::1 at 2019-05-13 12:05:52 +0900 Processing by ProductsController#show as HTML Parameters: {"id"=>"10"} User Load (5.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 ↳ app/controllers/products_controller.rb:9 Product Load (4.5ms) SELECT `products`.* FROM `products` WHERE `products`.`id` = 10 LIMIT 1 ↳ app/controllers/products_controller.rb:10 (4.2ms) SELECT `images`.`image` FROM `images` WHERE `images`.`product_id` = 10 ↳ app/controllers/products_controller.rb:11 Rendering products/show.html.haml within layouts/application Rendered products/_news.html.haml (4.8ms) Rendered products/_news.html.haml (0.6ms) Rendered products/_header.html.haml (41.6ms) User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 LIMIT 1 ↳ app/helpers/application_helper.rb:3 Like Load (0.4ms) SELECT `likes`.* FROM `likes` WHERE `likes`.`user_id` = 2 AND `likes`.`product_id` = 10 LIMIT 1 ↳ app/views/likes/_like.html.haml:3 Rendered likes/_like.html.haml (8.6ms) Rendered products/product-detail/_main.html.haml (28.9ms) Rendered products/product-detail/_comments.html.haml (12.0ms) Rendered products/product-detail/_media.html.haml (4.0ms) Rendered products/product-detail/_others.html.haml (31.7ms) Rendered products/_footer.html.haml (16.8ms) Rendered products/show.html.haml within layouts/application (157.0ms) Completed 200 OK in 250ms (Views: 226.8ms | ActiveRecord: 14.5ms)
odyu

2019/05/13 03:14

Redirected to http://localhost:3000/products/10 が原因ですかね。 コントローラーもコードをいかに修正してみてください。 def create @like = Like.new(user_id: session[:user_id], product_id: params[:product_id]) @like.save @likes_count = Product.find_by(id: params[:product_id]) # redirect_to @product render :create # <----- レンダリングする。もしかしたら省略できたかも end def destroy @like = Like.find_by(user_id: session[:user_id], product_id: params[:product_id]) @like.destroy # redirect_to @product render :destroy # <----- レンダリングする。もしかしたら省略できたかも end
kokotaro

2019/05/13 03:30

無事非同期できました!! レンダリングは省略できました。 今回はコントローラーのredirect_toの記述が読み込まれてしまいリダイレクトされ非同期できていなかったという解釈でよろしいでしょうか??
odyu

2019/05/13 03:32

そういうことです。 解決してよかったです
kokotaro

2019/05/13 03:33

今回の件でログを見て考えてみるということも学べました。 本当にありがとうございます。助かりました。
guest

回答1

0

自己解決

odyuさんのご指摘で無事解決しました。
今回の場合回答が質問への追記・修正の依頼の方に投稿されてしまっていてベストアンサーボタンが押せなかったのでこちらに転記して解決済みとさせていただきます。
odyuさんありがとうございます。

odyu

2019/05/13 12:14

Redirected to http://localhost:3000/products/10
が原因ですかね。

コントローラーもコードをいかに修正してみてください。

def create
@like = Like.new(user_id: session[:user_id], product_id: params[:product_id])
@like.save
@likes_count = Product.find_by(id: params[:product_id])

render :create # <----- レンダリングする。もしかしたら省略できたかも
end

def destroy
@like = Like.find_by(user_id: session[:user_id], product_id: params[:product_id])
@like.destroy

render :destroy # <----- レンダリングする。もしかしたら省略できたかも
end

投稿2019/05/13 03:54

kokotaro

総合スコア22

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問