□解決したいこと
いいね機能をAjaxにて実装したいと考えております。
https://gyazo.com/4981862a465699475bcfec773839c50d
以上の動画のようにいいねの解除はできるのですが、いいねを新しく投稿すると
ActionView::Template::Error (No route matches {:action=>"destroy", :controller=>"likes", :tip_id=>#<Tip id: 25, title: "テスト", category_id: 4, description: "Lorem ipsum dolor sit amet, consectetur adipiscing...", user_id: 1, created_at: "2021-05-20 13:57:31", updated_at: "2021-05-27 22:59:36", image: nil>}, missing required keys: [:id]): 1: <% if user_signed_in? %> 2: <% if current_user.already_liked?(@tip)%> 3: <%= link_to tip_like_path(@tip),method: :delete, remote: true do %> 4: <i class="fas fa-heart unlike-btn"></i> 5: <% end %> 6: <% else %> app/views/likes/_like_partial.html.erb:3 app/views/likes/create.js.erb:1
以上のエラーが発生します。
rails での実装に挙動は問題ないのですが、非同期処理のいいねを押す挙動だけうまくいきません。
□仮説及び調べたこと
エラー構文の中で:action=>"destroy"が行われています。今回は新たにいいねを押すため、destroyではなくpostが起動するはずです。
つまり、2行目
<% if current_user.already_liked?(@tip)%>
が正常に起動しておらず、条件分岐ができていないと考えました。
likes_controllerでbinding.pryで値を取得して確認しました。
def create @like = current_user.likes.new(tip_id: params[:tip_id]) @tip = Tip.find_by(id: params[:tip_id]) binding.pry @like.save end [1] pry(#<LikesController>)> current_user.already_liked?(@tip) Like Exists? (0.4ms) SELECT 1 AS one FROM `likes` WHERE `likes`.`user_id` = 2 AND `likes`.`tip_id` = 25 LIMIT 1 ↳ app/models/user.rb:17:in `already_liked?' => false
current_user.already_liked?(@tip)を打ち込んで確認しましたが、
値はfalseとなりました。つまり、現在のユーザーはいいねをしていない状態ということです。
これからいいねをしようとしている状態ですので、状態としては問題ないはずです。
しかし、actionはdestroyとなっており、if current_user.already_liked?(@tip)がtrueである場合の挙動をしております。
なぜこのような挙動となるかがわかりません。
もし、何か原因がお分かりの方がいらっしゃいましたらご教示ただきたくお願い申し上げます。
##□環境
rails (6.0.3.7)
ruby 2.6.5
##□問題のコード
html
1tips/show.html 2 3<div class = "wrapper"> 4 <%= render "shared/header" %> 5 <div class="main-tips-show"> 6 <div class="like-show" id='likes_buttons_<%= @tip.id %>'> 7 <%= render partial:'likes/like_partial' %> 8 </div> 9 <以下省略>
html
1_like_partial/html.erb 2 3<% if user_signed_in? %> 4 <% if current_user.already_liked?(@tip)%> 5 <%= link_to tip_like_path(@tip),method: :delete, remote: true do %> 6 <i class="fas fa-heart unlike-btn"></i> 7 <% end %> 8 <% else %> 9 <%= link_to tip_likes_path(@tip),method: :post, remote: true do %> 10 <i class="far fa-heart like-btn" ></i> 11 <% end %> 12 <% end %> 13<% else %> 14 <i class="far fa-heart like-btn" ></i> 15<% end %> 16<p><%=@tip.likes.count %> </p>
ruby
1create.js.erb 及び destroy.js.erb 2 3$('#likes_buttons_<%= @tip.id %>').html("<%= j(render partial: 'likes/like_partial') %>");
ruby
1likes_controller.rb 2 3class LikesController < ApplicationController 4 def create 5 @like = current_user.likes.new(tip_id: params[:tip_id]) 6 @tip = Tip.find_by(id: params[:tip_id]) 7 binding.pry 8 @like.save 9 end 10 11 def destroy 12 @like = Like.find_by(tip_id: params[:tip_id], user_id: current_user.id) 13 @like.destroy 14 @tip = Tip.find_by(id: params[:tip_id]) 15 end 16end
ruby
1 2user.rb 3 4class User < ApplicationRecord 5 devise :database_authenticatable, :registerable, 6 :recoverable, :rememberable, :validatable 7 8 validates :nickname, presence: true, length: { maximum: 6 } 9 validates :password, presence: true, format: { with: /[a-z\d]{6,}/i, message: 'は半角英数6文字以上としてください' } 10 with_options presence: true, format: { with: /\A[ぁ-んァ-ヶ一-龥々]+\z/, message: 'には全角文字を使用してください' } do 11 validates :last_name 12 validates :first_name 13 end 14 15 has_many :tips 16 has_many :comments 17 has_many :likes 18 has_many :liked_tips, through: :likes, source: :tip 19 def already_liked?(tip) #←すでにいいねしているかの記述 20 self.likes.exists?(tip_id: tip.id) 21 end 22end
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/05/29 12:40 編集
2021/05/30 00:00
2021/05/30 07:03 編集
2021/05/30 07:44 編集
2021/05/30 10:24 編集
2021/05/30 11:09 編集
2021/05/30 11:29
2021/05/31 13:05