前提・実現したいこと
閲覧ありがとうございます。
三ヶ月目の初学者のため、文章など稚拙な部分はご容赦いただければと思います。
Ruby on rails で写真投稿型のアプリを作っています。
モデルはPost,User,Likeの3つです。
投稿の詳細画面(posts/show.html.erb)にいいねボタンを設置し、ajaxで「イイネ」⇄「イイネを取り消す」にしたいのですがうまくいきません。
厳密にはデータは送られているがそのビューで反映してくれない状態です。
(投稿詳細ページ → 「イイネ」ボタンを押す → topに戻る → 再び投稿詳細ページへ → 「イイネを取り消す」(イイネ数1)となっていたので、データは送られています。)
下記ソースコードになります。
該当のソースコード
- models/post.rb
class Post < ApplicationRecord mount_uploader :image, ImageUploader default_scope -> { order(created_at: :desc) } belongs_to :user has_many :likes has_many :liked_users, through: :likes, source: :user end
- models/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 has_many :posts, dependent: :destroy has_many :likes, dependent: :destroy has_many :liked_posts, through: :likes, source: :post def already_liked?(post) self.likes.exists?(post_id: post.id) end end
- models.like.rb
class Like < ApplicationRecord belongs_to :post belongs_to :user validates_uniqueness_of :post_id, scope: :user_id end
- likes_controller.rb
class LikesController < ApplicationController def create @like = current_user.likes.create(post_id: params[:post_id]) end def destroy @like = Like.find_by(post_id: params[:post_id], user_id: current_user.id) @like.destroy end end
- posts_controller.rb
Ruby
1class PostsController < ApplicationController 2 3 def show 4 @post = Post.find(params[:id]) 5 end 6 7end
- posts/show.html.erb
Ruby
1<div class="detail"> 2 <%= image_tag @post.image.url, :size =>'480x480' %> 3 <%= simple_format(@post.text) %> 4 <div id="likes_buttons_<%= @post.id %>"> 5 <%= render partial: 'likes/like', locals: { post: @post } %> 6 </div> 7 <div class="like_count"> 8 <%= @post.likes.count %> 9 </div> 10 <div class="liked_user"> 11 <li>イイネしたユーザー</li> 12 <% @post.liked_users.each do |user| %> 13 <li><%= user.nickname %></li> 14 <% end %> 15 </div> 16</div>
- likes/_like.html.erb
Ruby
1<% if current_user.already_liked?(post) %> 2 <%= button_to 'イイネを取り消す', post_like_path(post), method: :delete, remote: true %> 3<% else %> 4 <%= button_to 'イイネ', post_likes_path(post), method: :post, remote: true %> 5<% end %>
- likes/create.js.erb
$('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'likes/like', locals: {post: @post}) %>");
- likes/destroy.js.erb
$('#likes_buttons_<%= @post.id %>').html("<%= j(render partial: 'likes/like', locals: {post: @post}) %>");
コードが多く申し訳ありません、、、
試したこと/補足
- 恥ずかしながらajaxを完璧に理解できておらず、どの変数が何を指しているのか混乱しています。
_like.html.erbのpostを@postに変えてみたりしましたがなかなかうまく動きません。
- ユーザーがalready_likedかどうかは判断できているようです。
データは送られているが、非同期で反映してくれない状態?(create.jsやdestroy.jsが原因のような気がします)
その他補足情報
OS : mac
環境 : cloud9
データベース : mysql
ruby バージョン : ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
rails バージョン : 5.2.3
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/09/10 08:19
2019/09/10 08:25
2019/09/12 10:39