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

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

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

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

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

JavaScript

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

非同期処理

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

Q&A

解決済

1回答

2619閲覧

いいねの非同期通信後、いいねのカウントがおかしい

susume

総合スコア13

Ruby on Rails 5

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

Haml

Haml(HTML abstraction markup language)は、HTML/XHTMLを効率的に記述するためのマークアップ言語および記法です。

JavaScript

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

非同期処理

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

0グッド

0クリップ

投稿2020/08/01 08:37

前提・実現したいこと

いいねを非同期通信において、いいねのカウントを正しく表示させたいです。
画像のようにいいねの非同期通信はできているのですが、いいねを押すとカウントがおかしくなり正確ないいね数を表示させることができません。

いいねの非同期通信はできている
イメージ説明
イメージ説明

しかし、いいねのカウントがおかしい
イメージ説明
イメージ説明
※右側の投稿のいいねを押すと、左側の投稿のいいねが取り消される
※また、いいねの非同期通信は、左側の投稿のみに反映される。
右側の投稿にはいいねの非同期通信は適用されない。リロードすればいいねの更新はされる。

該当のソースコード

ruby:_favorite.html.haml

- if user_signed_in? - if current_user.already_favorited?(post) = link_to post_favorites_path(post), method: :delete, remote: true do = icon('fas', 'thumbs-up') - else = link_to post_favorites_path(post), method: :post, remote: true do = icon('far', 'thumbs-up') = post.favorites.count

post/index.html.haml

.posts-profile-box__favoritesBox .posts-profile-box__favoritesBox__favorite#favorites = render partial: "favorites/favorite", locals: { post: post }

favorites/create.js.erb

$('#favorites').html("<%= j(render partial: 'favorite', locals: { post: @post }) %>");

favorites/destroy.js.erb

$('#favorites').html("<%= j(render partial: 'favorite', locals: { post: @post }) %>");

favorites.controller

class FavoritesController < ApplicationController before_action :snow_post def create @favorite = Favorite.create(user_id: current_user.id, post_id: params[:post_id]) @favorites = Favorite.where(post_id: params[:post_id]) end def destroy @favorite = Favorite.find_by(user_id: current_user.id, post_id: params[:post_id]) @favorite.destroy @favorites = Favorite.where(post_id: params[:post_id]) end private def snow_post @post = Post.find(params[:post_id]) end end

favorite.rb

class Favorite < ApplicationRecord belongs_to :user belongs_to :post validates_uniqueness_of :post_id, scope: :user_id end

post.rb

class Post < ApplicationRecord belongs_to :user attachment :image has_many :favorites, dependent: :destroy has_many :comments with_options presence: true do validates :title validates :body validates :image end end

user.rb

class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable validates :name, presence: true, uniqueness: true attachment :profile_image has_many :posts, dependent: :destroy has_many :favorites, dependent: :destroy has_many :comments def already_favorited?(post) self.favorites.exists?(post_id: post.id) end end

試したこと

こちらの記事を参考にいいねの実装を試みています。
https://qiita.com/yuto_1014/items/78d8b52d33a12ec33448

同期通信はできていたので、create.js.erbなどの記述に誤りがあるのかなと思いましたが、特に見当たらず。

そもそもデータベースに登録されない?とも思いましたが、データベースには問題なくいいねのデータが送信されていました。
イメージ説明
※いいねボタンを押すとデータが記録され、もう一度押すとデータが削除されるようになっています。

いくつかの記事を参考にさせてもらいましたが、自分では対処できず、お助け願います。

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

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

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

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

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

guest

回答1

0

ベストアンサー

favorites/destroy.js.erb が $('#favorites').html() になっています。つまり誰のPostに良いね、取消 しようと '#favorites' を書き換えます。

post/index.html.haml ですが、これが全部ではないですね?その前に
@posts.each do |post| みたいなのが有りますね?
そのloopのなかに .posts-profile-box__favoritesBox__favorite#favorites が有ります。
つまりどのpostも #favoritesなわけです。
この場合 JSは最初に見つけた #favorites を、「あった!ここだ」と書き直します。結果、常に最初(左)の良いねが書き換えられます。

投稿2020/08/01 10:13

winterboum

総合スコア23567

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

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

susume

2020/08/01 10:33

ご回答ありがとうございます。 ご指摘にあるようにindex.html.hamlは全てではないです。 ``` .posts-index - @posts.each do |post| .posts-box .posts-box__image = link_to post_path(post) do = attachment_image_tag post, :image .posts-profile-box .posts-profile-box__image = link_to user_path(post.user.id) do = attachment_image_tag post.user, :profile_image, fallback: "no-image.png" .posts-profile-box__username %h1= link_to post.user.name, user_path(post.user.id) .posts-profile-box__favoritesBox .posts-profile-box__favoritesBox__favorite#favorites = render partial: "favorites/favorite", locals: { post: post } .posts-profile-updateat = post.updated_at.strftime("%Y-%m-%d %H:%M") ``` これが全文になります。 となると、正しくいいねがカウントされるようにするためには、 $('#favorites').html()→$('.posts-index').html()に変更し、.posts-profile-box__favoritesBox__favorite#favoritesの#favoriteは削除するという認識でよろしいでしょうか?
winterboum

2020/08/01 10:45 編集

いえ、それですと全ての '.posts-index'が書き換わってしまいます。 .posts-profile-box__favoritesBox__favorite#favorites の id favorites に "favorites-#{post.id}" の様に全てのpostで異なるidになるようにしてください。 で favorites/create.js.erb では `$("#favorites-#{params[:id]}") ` とする。(’ でなく " で囲み直す) なお、hamlで "favorites-#{post.id}" で id='favorites-12" となってくれるか分からないので、その時は haml の手引を読んで。 slimなら  .posts-profile-box__favoritesBox__favorite id="favorites-#{post.id}" ですが
susume

2020/08/01 13:27

ご回答ありがとうございます。 .posts-profile-box__favoritesBox__favorite %div{id: "favorite_#{post.id}"} この記述でうまくいいねの非同期通信ができました。 create.js.hamlも $("#favorite_#{@post.id}").html("#{j(render partial: 'favorite', locals: { post: @post })}");これで無事に非同期通信といいねのカウントができました。 参考記事 https://qiita.com/kaito_program/items/c486354196e67b5d11e0 ただ一点レイアウトがずれてしまったので要素を横並びにしようとscssで修正しようとしたところ、 #favorite_#{post.id} { display: flex; } 上記の記述では構文エラーが出ました。 #favorite_#{post.id}のscssの当て方ってどのように当てればいいのでしょうか?? 記事を調べても基本的なid属性のcssの当て方しか出てこないため、ご教示お願いいたします。
winterboum

2020/08/01 19:48

それは当てられないので、cssはclassの方で当ててください
susume

2020/08/02 11:42

そうなんですね!勉強になりました。 おかげさまでhtmlに直接styleでcssを当てることで横並びにできました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問