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

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

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

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

Ruby

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

Q&A

解決済

1回答

1551閲覧

ログイン機能なしでの「いいね」機能【Rails】

shutag

総合スコア1

Ruby on Rails 5

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

Ruby

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

0グッド

0クリップ

投稿2021/06/26 18:52

編集2021/06/27 04:25

前提・実現したいこと

初めての投稿かつプログラミング初学者につき、わかりにくい点があれば申し訳ありません。

現在railsでアプリ開発をしており、投稿に対して、ユーザーログイン機能無しでの「いいね」機能の実装に取り組んでいます。
過去の投稿などもみて、cookieを利用することで、原則として同一ユーザーが複数回の「いいね」はできない形にすることを考えています。
(あくまでcookieですから、別ブラウザの利用等によって、複数回のいいねをすることも可能ですが、それはやむなしと考えています)

発生している問題・エラーメッセージ

非同期のいいね機能を作成することまではできたのですが、ページの更新をすると、元に戻ってしまう。具体的には、、、、

①いいねをクリックする前はこんな状態。
イメージ説明

②いいねをクリックするとこうなる。
イメージ説明

③ページを更新すると、元に戻ってしまう(いいね数は計上されている)
イメージ説明

該当のソースコード

ContentsModel

1class Content < ApplicationRecord 2 has_many :favorites, dependent: :destroy 3 ransacker :favorites_count do 4 query = '(SELECT COUNT(favorites.content_id) FROM favorites where favorites.content_id = contents.id GROUP BY favorites.content_id)' 5 Arel.sql(query) 6 end 7end

FavoritesModel

1class Favorite < ApplicationRecord 2 belongs_to :content 3end

Table

1ActiveRecord::Schema.define(version: 2021_06_26_132254) do 2 create_table "contents", force: :cascade do |t| 3 (略) 4 end 5 6 create_table "favorites", force: :cascade do |t| 7 t.integer "content_id" 8 t.datetime "created_at", null: false 9 t.datetime "updated_at", null: false 10 end 11end

index.html.erb

<div class="album py-5 bg-light mt-3"> <div class="container"> <div class="row"> <% @contents.each do |content| %> <div class="col-md-4"> <div class="card border-dark mb-4 shadow-sm"> <div class="card-header text-white bg-dark" style="height: 5rem;"> <h6><%= content.group %> <p class="small"><%= content.team %></p> </h6> </div> <div class="card-body h6" style="height: 15rem;"> <p><%= link_to content.title.to_s.truncate(88), "#{content.url}" %></p> <p class="card-text"><small class="text-muted"><%= content.author.to_s.truncate(26) %></small></p> </div> <div class="card-footer bg-transparent border-info d-flex align-items-center" style="height: 2rem;"> <!--いいね機能。_list_favorites.html.erbにrenderしています。--> <div class="favorite-<%= content.id %> text-nowrap"> <%= render "favorites/list_favorite", content: content, favorites_count: content.favorites.length, cookies: cookies %> </div> </div> </div> </div> <% end %> </div> <%= paginate @contents %> </div> </div>

_list_favorites.html.erb

<% if cookies.nil? %> <%= link_to content_favorites_path(content), method: :post, remote: true do %> <span class="far fa-heart like" id="like-<%= content.id %>"></span> <% end %> <% else %> <% arr = cookies.to_s.split(",").map(&:to_i) %> <% if arr.include?(content.id) %> <span class="fas fa-heart unlike" id="unlike-<%= content.id %>"></span> <% else %> <%= link_to content_favorites_path(content), method: :post, remote: true do %> <span class="far fa-heart like" id="like-<%= content.id %>"></span> <% end %> <% end %> <% end %> <%= favorites_count %>

FavoritesController

1class FavoritesController < ApplicationController 2 def create 3 @content = Content.find(params[:content_id]) 4 if cookies[:favorite_content_id].nil? 5 cookies.permanent[:favorite_content_id] = @content.id.to_s 6 else 7 cookies.permanent[:favorite_content_id] = cookies.permanent[:favorite_content_id] + "," + @content.id.to_s 8 end 9 Favorite.create(content_id: @content.id) 10 @favorites_count = @content.favorites.count 11 @cookies = cookies[:favorite_content_id] 12 end 13end

ContentsController

1class ContentsController < ApplicationController 2 def index 3 if params[:q].present? 4 @q = Content.ransack(params[:q]) 5 else 6 params[:q] = { sorts: 'favorites_count desc'} 7 @q = Content.ransack() 8 end 9 10 @contents = @q.result.page(params[:page]) 11 @contents_all = Content.select(:author).distinct 12 end 13end

試したこと

以下のqiitaの投稿も参考にしながら作成し、コードのずれもないはずなのですが、原因がわかりません。。。

https://qiita.com/yuta-pharmacy2359/items/85653210cd2229dd4973

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

ruby 2.7.3
rails 5.2.2

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

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

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

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

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

winterboum

2021/06/27 03:22

view にある content はどこでどう定義してますか
shutag

2021/06/27 03:44

ありがとうございます。 contentはモデルで以下のように定義しています class Content < ApplicationRecord has_many :favorites, dependent: :destroy ransacker :favorites_count do query = '(SELECT COUNT(favorites.content_id) FROM favorites where favorites.content_id = contents.id GROUP BY favorites.content_id)' Arel.sql(query) end end また、contents controllerのコードも記載させていただきます。 class ContentsController < ApplicationController def index if params[:q].present? @q = Content.ransack(params[:q]) else params[:q] = { sorts: 'favorites_count desc'} @q = Content.ransack() end end @contents = @q.result.page(params[:page]) @contents_all = Content.select(:author).distinct end
winterboum

2021/06/27 04:05

質問編集して、そちらに <cod3e>で書いてほしい
winterboum

2021/06/27 04:06

viewの中の変数contentはどこで代入されてますか
shutag

2021/06/27 04:26

ありがとうございます。質問編集いたしました。 contentは大元のindexファイルで代入しています(こちらも質問編集して載せさせていただきました)
guest

回答1

0

ベストアンサー

cookies が問題の元ですね。
index.html で cookies: cookies している cookies は ActionController::Cookie の cookies だということになりますが、list_favorites.html.erb の cookies は cookies: で渡ってきた cookiesなのかActionController::Cookie のなのかどちら?
(どちらにしても、指しているのは ActionController::Cookie の cookiesではありますが)
ここは favorite_content_ids = cookies[:favorite_content_id]
として、きちんと名前を分ける所から整理しなおしましょう。

で、cookies.to_s.split(",") の cookiesはActionController::Cookie の cookies であって cookies[:favorite_content_id]ではないから、splitしても content.id に一致するものは出てきません。
なお、そこを正しくしても splitの結果は String、 content.id は Integer なので一致しません。

投稿2021/06/27 04:54

winterboum

総合スコア23401

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

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

shutag

2021/06/27 05:24

ありがとうございます!favorite_content_ids = cookies[:favorite_content_id]とすることで、うまく機能するようになりました。(おっしゃるとおり、stringとintegerの違いがあるのでダメかなと思いましたが、ここの部分は修正せずとも機能しています、、、) いずれにしましても、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問