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

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

詳細はこちら
Ruby

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

Ruby on Rails 6

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

Q&A

解決済

1回答

857閲覧

いいね機能を非同期で実装したい

taba.3011

総合スコア12

Ruby

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

Ruby on Rails 6

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Bootstrap

BootstrapはウェブサイトデザインやUIのWebアプリケーションを素早く 作成する可能なCSSフレームワークです。 Twitter風のデザインを作成することができます。

0グッド

0クリップ

投稿2021/01/28 03:18

編集2021/01/29 05:23

前提・実現したいこと

いいねボタンを非同期通信で実装したいです。
現状、ブラウザをリロードしなければアイコンの色が変化しません。
いいね機能を非同期で実装しているサイトを参考にして実装しようとしていたのですが上手くいかず、若干違うやり方をしているサイトの方法に変えてみたりしているのですが、中々改善されません。

初心者のため、jqueryやwebpackなどの設定がまだ理解できておらず、コピペに頼ってしまっているところがあるので根本的なミスも見落としがちですが、どなたかご教授いただけると助かります。

routes.rb
Rails.application.routes.draw do devise_for :users root to: 'articles#index' resources :articles do collection do get 'search' end resources :comments, only: :create resources :likes, only: [:create, :destroy] end end

#####article.rb

class Article < ApplicationRecord belongs_to :user has_many :likes def like_user(user_id) likes.find_by(user_id: user_id) end end

#####likes_controller.rb

class LikesController < ApplicationController before_action :article_params, only: [:create, :destroy] def create @like = Like.create(article_id: params[:article_id], user_id: current_user.id) end def destroy Like.find_by(article_id: params[:id], user_id: current_user.id).destroy end private def article_params @article = Article.find(params[:article_id]) end end

#####_like.html.erb

<% if user_signed_in? %> <% unless @article.like_user(current_user.id).blank? %> <%= link_to article_like_path(article_id: @article.id, id: @article.likes[0].id), method: :delete, remote: true do %> <div class="vertical_like"> <p class="like-button"><i class="fas fa-heart fa-2x" style="color: #e82a2a;"></i><span style="color: #e82a2a"><%= @article.likes.count %></span></p> </div> <% end %> <% else %> <%= link_to article_likes_path(@article.id), method: :post, remote: true do %> <div class="vertical_like"> <p class="like-button"><i class="far fa-heart fa-2x" style="color: #e82a2a;"></i><span style="color: #e82a2a"><%= @article.likes.count %></span></p> </div> <% end %> <% end %> <% end %>

create.js.erb

$('.likes_buttons').html("<%= j(render partial: 'likes/like', locals: {article: @article}) %>");

#####destroy.js.erb

$('.likes_buttons').html("<%= j(render partial: 'likes/like', locals: {article: @article}) %>");

#####application.html.erb

<!DOCTYPE html> <html> <head> <title>Stockapp</title> <%= csrf_meta_tags %> <%= csp_meta_tag %> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script> </head> <body class="wrapper"> <header> <%= render "shared/header" %> </header> <%= yield %> <footer> <%= render "shared/footer" %> </footer> </body> </html>

application.js

// This file is automatically compiled by Webpack, along with any other files // present in this directory. You're encouraged to place your actual application logic in // a relevant structure within app/javascript and only use these pack files to reference // that code so it'll be compiled. require('jquery'); require("@rails/ujs").start() // require("turbolinks").start() require("@rails/activestorage").start() require("channels") require("./tag") require("./preview") require("./count") require("bootstrap"); // Uncomment to copy all static images under ../images to the output folder and reference // them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>) // or the `imagePath` JavaScript helper below. // // const images = require.context('../images', true) // const imagePath = (name) => images(name, true) //= require bootstrap-sprockets import "bootstrap" import "../src/application.scss" import "@fortawesome/fontawesome-free/js/all"

#####environment.js

const { environment } = require('@rails/webpacker'); const webpack = require('webpack'); environment.plugins.append('Provide', new webpack.ProvidePlugin({ $: 'jquery/src/jquery', jQuery: 'jquery/src/jquery' }) ); module.exports = environment;

試したこと

jsファイルにalertを記述し、確認したところ、ちゃんと作動しました。
#####create.js.erb

$('.likes_buttons').html("<%= j(render partial: 'likes/like', locals: {article: @article}) %>"); alert('create呼ばれた!!');

#####destroy.js.erb

$('.likes_buttons').html("<%= j(render partial: 'likes/like', locals: {article: @article}) %>"); alert('destroy呼ばれた!!');

しかし連続でタップしたところ、createは連続でアラートが表示されるのですが、destroyのアラートは最初しか常時されず、2回目以降はconsoleに
rails-ujs.js:216 DELETE http://localhost:3000/articles/14/likes/11 500 (Internal Server Error)
./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js.Rails.ajax @ rails-ujs.js:216
./node_modules/@rails/ujs/lib/assets/compiled/rails-ujs.js.Rails.handleRemote @ rails-ujs.js:652
(anonymous) @ rails-ujs.js:172
というエラーが出でしまいます。
なんとなく、AJAX通信ができていないのかな?という予想はできるのですが、そこからの対処法がわかりません。

補足情報(FW/ツールのバージョンなど)

rails 6.0.3.4

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

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

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

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

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

guest

回答1

0

自己解決

likes_controller.rbのデストロイアクションの、
Like.find_by(article_id: params[:id], user_id: current_user.id).destroyのparams[:id]をparams[:article_id]にする。

_like.html.erbの3行目、article_like_path → articles_like_pathにする。

上記を修正したらうまくいきました!
コントローラーでidが受け取れていなかったことに加え、ルーティングができていなかったことが原因でした。

投稿2021/01/29 05:27

taba.3011

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問