前提・実現したいこと
投稿した写真にいいねを付けられるようにしたいと思い
下記の記事を参考にさせていただき、実装を試した所
うまくいかずエラーが出てしまいます。
https://qiita.com/YuitoSato/items/94913d6a349a530b2ea2
https://qiita.com/kaito_program/items/c486354196e67b5d11e0
まず、どのようないいね機能を付けたいかというと
1.ログインユーザーがいいねを付けられる。
2.いいねができるのは1回だけ。
3.いいねはハートのアイコンになっており、最初は黒いハートだが、押すと非同期通信にて赤いハートに変わる。
4.いいねをされた数を一緒に表示させる。
以上になります。
プログラミング初心者のため、とりあえず参考記事をコピペなどして試してから理解に努めようとしております。そのため、簡単なミスもわからずに見落としがちですが、どなたかご教授いただけると助かります。
発生している問題・エラーメッセージ
条件によってエラーの内容が異なります。
1.トップページから投稿詳細ページへ遷移できない。
これは、投稿者は詳細ページへ遷移できるが、投稿者以外のログインユーザーが詳細ページへ遷移しようとすると下記のエラーが発生するものです。
追記:解決済み
**NameError in Posts#show** undefined local variable or method `like' for #<#<Class:0x00007fdf2225dfb0>:0x00007fdf2225c458>
2.投稿者本人が自分の投稿にもいいねが押せるはずだが、ログアウト状態者ようのなにも反応しない黒いハートのまま
追記:解決済み
3.いいねがされた数を表示するためのコードを書くとエラーが出てしまう。
追記:解決済み
4.ページをリロードするといいねが反映され、データベース上にも保存されるが、非同期通信ができない。
VM210:1 Uncaught ReferenceError: $ is not defined at <anonymous>:1:1 at processResponse (rails-ujs.js:283) at rails-ujs.js:196 at XMLHttpRequest.xhr.onreadystatechange (rails-ujs.js:264) (anonymous) @ VM210:1 processResponse @ rails-ujs.js:283 (anonymous) @ rails-ujs.js:196 xhr.onreadystatechange @ rails-ujs.js:264 XMLHttpRequest.send (async) ./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 3index.js:13 Uncaught TypeError: Cannot set property 'src' of null at slideshow_timer (index.js:13)
該当のソースコード
routes
1 resources :posts do 2 resources :comments, only: :create 3 resources :likes, only: [:create, :destroy] 4 end
:commentsは別機能実装のため、ネストしてあるので無視してください。
controller
1#いいね機能のコントローラー 2class LikesController < ApplicationController 3 before_action :set_post 4 5 def create 6 @like = Like.create(user_id: current_user.id, post_id: params[:post_id]) 7 @likes = Like.where(post_id: params[:post_id]) 8 @like.save 9 @post = @like.post 10 end 11 12 def destroy 13 like = Like.find_by(user_id: current_user.id, post_id: params[:post_id]) 14 like.destroy 15 @likes = Like.where(post_id: params[:post_id]) 16 @post.reload 17 end 18 19 private 20 21 def set_post 22 @post = Post.find(params[:post_id]) 23 end 24 25end 26
controller
1#念の為記載、投稿機能のコントローラー(showアクション部分) 2 def show 3 @comment = Comment.new 4 @comments = @post.comments.includes(:user) 5 end
model
1#いいね機能側 2class Like < ApplicationRecord 3 belongs_to :post, counter_cache: :likes_count 4 belongs_to :user 5 6 validates :post_id, uniqueness: { scope: :user_id } 7end 8
model
1#投稿機能側 2class Post < ApplicationRecord 3 belongs_to :user 4 has_many :likes, dependent: :destroy 5 6 def like_user(user_id) 7 likes.find_by(user_id: user_id) 8 end 9 10end
view
1#部分テンプレート views/likes/_like.html.erb 2 3<% if user_signed_in? %> 4 5 <% unless post.like_user(current_user.id).blank? %> 6 <%= link_to post_like_path(post_id: post.id ,id: post.likes[0].id), method: :delete, remote: true do %> 7 <div class="vertical_like"> 8 <%= image_tag("icon_red_heart.png") %> 9 <span class="red-text"> 10 <%= post.likes_count %> 11 </span> 12 </div> 13 <% end %> 14 <% else %> 15 <%= link_to post_likes_path(post.id), method: :post, remote: true do %> 16 <div class="vertical_like"> 17 <%= image_tag("icon_heart.png") %> 18 <span class="grey-text text-darken-2"> 19 <%= post.likes_count %> 20 </span> 21 </div> 22 <% end %> 23 <% end %> 24 25<% else %> 26 27 <% if post.likes_count > 0 %> 28 <div class="vertical_like"> 29 <i class="material-icons red-text">favorite</i> 30 <span class="red-text"> 31 <%= post.likes_count %> 32 </span> 33 </div> 34 <% else %> 35 <div class="vertical_like"> 36 <i class="material-icons grey-text text-darken-2">favorite_border</i> 37 <span class="grey-text text-darken-2"> 38 <%= post.likes_count %> 39 </span> 40 </div> 41 <% end %> 42 43<% end %> 44 45 46
likeモデルにてcounter_cacheの記述を書いているので、post.like_countとするだけでその投稿に結びつくlike数が表示されます。と参考記事にありましたが、<%= post.like_count %>を書くとエラーが出てしまいます。
ちなみにlike_countのカラムはpostテーブルに追加済みで、型はitegerで設定しています。
追記:上記エラー解決済み
js
1#views/likes/create.js.erb 2$('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'likes/like', locals: {post: @post}) %>"); 3 4#views/likes/destroy.js.erb 5$('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'likes/like', locals: {post: @post}) %>");
追加:呼び出したい部分で↓
html
1 <div id="likes_buttons_<%= @post.id %>"> 2 <%= render partial: 'likes/like', locals: { post: @post, likes: @likes}, id:"likes_buttons_" %> 3 </div>
追記:likesコントローラー、部分テンプレート、JavaScriptはサイト内の質問を参考に編集されています。
試したこと
おそらく条件式を記事のままコピペしてしまったので、自分の実装したいいいね機能と異なる条件式になっていることはなんとなく理解できている。
なので条件の部分テンプレートのところの<% if user_signed_in? %>を<% if user_signed_in? && current_user.id != @post.user_id %>にしてみたりと試しました。
結果は遷移はできるようになったので、エラーの1の部分は解消されたかと思います。しかし、いいねボタンのアイコンが押せないエラーは継続しています。
以上になります。
他の情報が必要な場合は教えていただけると助かります。
宜しくおねがいします!
追記:上記エラーの1,2,3はサイト内の"https://teratail.com/questions/245199"様の質問を参考に(正確には質問者様の参考サイト)解決いたしました。
ただ、非同期通信にはならず、新たに4のエラーがでています。こちらのエラーはサイト内の質問を参考にして色々試しましたが、現在も解決できていません。
アドバイスをいただける方がいましたらお願いします
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー