以下のサイトを参考にして非同期通信を使ったいいね機能を実装しようと思ったのですが、エラーの解決ができません。
【Rails】いいね機能完全版!同期いいね、いいね数の表示、非同期いいね、アイコン表示、それぞれの実装方法についてまとめて解説
CREATE 500 internal server rails-ujs.js:216 error
とコンソールに出てきます(検証ツール)
原因としては、javasctiptで返さないといけないのにHTMLで返されてしまっているからだと考えました。
なのでいいね機能を実装しているコントローラーを
class LikesController < ApplicationController before_action :post_params def create Like.create(user_id: current_user.id, post_id: params[:id]) end def destroy Like.find_by(user_id: current_user.id, post_id: params[:id]).destroy end private def post_params @post = Post.find(params[:id]) end end
#問題のソースコード
ルーティング
Rails.application.routes.draw do devise_for :users resources :movies do resources :movie_comments, only: %i[create destroy] end resources :posts do resources :comments, only: %i[create destroy] end post 'like/:id', to: 'likes#create', as: 'create_like' delete 'like/:id', to: 'likes#destroy', as: 'destroy_like' post 'movie_like/:id', to: 'movie_likes#create', as: 'create_movie_like' delete 'movie_like/:id', to: 'movie_likes#destroy', as: 'destroy_movie_like' root 'posts#index' end
いいね機能に関する部分テンプレート(_like.html.erb)
<% if user_signed_in? %> <div class="like"> <h3>いいね件数: <%= post.likes.count %></h3> <div class = 'like-button'> <% if current_user.liked_by?(post.id) %> <td><%= link_to 'いいねを外す', destroy_like_path(post), class: "like-link", method: :DELETE,remote: true %></td> <i class="fa fa-heart unlike-btn"></i> <% else %> <td><%= link_to 'いいね', create_like_path(post), class: "like-link", method: :post, remote: true %></td> <i class="fa fa-heart like-btn"></i> <% end %> </div> </div> <% end %>
いいね機能(ajax)部分に関するテンプレート
名前:create.js.erb
document.getElementById('post_<%= @post.id %>').innerHTML = '<%= j(render @post) %>' alert('いいねが押せている!');
同じくいいね機能(ajax)部分に関するテンプレート
名前:destroy.js.erb
document.getElementById('post_<%= @post.id %>').innerHTML = '<%= j(render @post) %>'
alertは確認のために載せているので、後々削除します
投稿一覧のコード
<div class="content-wrapper"> <div class="content-block"> <% @posts.each do |post| %> <div class="content"> <div class="user-about"> <div class="image"> <% if post.user.image.attached? %> <%= image_tag post.user.image %> <% else %> <%= image_tag 'no.user.png' %> <% end %> </div> <div class="profile"> <div class="name-history"> <div class="name"> <%= post.user.nickname %> </div> <div class="mania-histry"> <%= "学習歴:#{post.user.mania_histry}年" %> </div> </div> <div class="enjoy-point"> <%= "楽しいポイント#{post.user.enjoy_point}"%> </div> </div> </div> <div class="text"> <p><%= post.content %></p> </div> <% if post.images.attached? %> <% post.images.each do |image| %> <div class = 'images'> <%= image_tag image, class: "content-image" %> </div> <% end %> <% end %> <div class="action-menu"> <tr id="post_<%= post.id %>"> <%= render 'post', post: post %> </tr> <div class="comment"> <h3>コメント件数: <%= post.comments.count %></h3> <%= link_to "コメントする", "/posts/#{post.id}", class: "comment-buttom" %> </div> <%if user_signed_in?%> <% if current_user.id == post.user.id %> <%= link_to "編集", edit_post_path(post) %> <%= link_to "削除", post_path(post), method: :delete %> <% end %> <% end %> </div> </div> <% end %> </div> <div class="sidebar"> <%= render 'shared/menu'%> </div> </div>
##続いていいね機能に関するコントローラーです
class LikesController < ApplicationController before_action :post_params def create Like.create(user_id: current_user.id, post_id: params[:id]) end def destroy Like.find_by(user_id: current_user.id, post_id: params[:id]).destroy end private def post_params @post = Post.find(params[:id]) end end
##続いていいね機能に関するモデルです
class Like < ApplicationRecord belongs_to :user belongs_to :post end
いいねするユーザーに関するモデルです
class User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable has_one_attached :image has_many :posts has_many :likes has_many :movielikes has_many :comments, dependent: :destroy has_many :movies def liked_by?(post_id) likes.where(post_id: post_id).exists? end with_options presence: true do validates :nickname validates :mania_histry validates :enjoy_point validates :email validates :password, length: { minimum: 6 } end validate :image_presence def image_presence if image.attached? if !image.content_type.in?(%('image/jpeg image/png')) errors.add(:image, 'にはjpegまたはpngファイルを添付してください') end else errors.add(:image, 'ファイルを添付してください') end end end
#エラーログ
method: postに変更しました
Started DELETE "/like/2" for 172.24.0.1 at 2021-04-06 01:31:40 +0000 web_1 | Cannot render console from 172.24.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1 web_1 | Processing by LikesController#destroy as JS web_1 | Parameters: {"id"=>"2"} web_1 | Post Load (0.6ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 2 LIMIT 1 web_1 | ↳ app/controllers/likes_controller.rb:15:in `post_params' web_1 | User Load (0.7ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1 web_1 | ↳ app/controllers/likes_controller.rb:9:in `destroy' web_1 | Like Load (0.8ms) SELECT `likes`.* FROM `likes` WHERE `likes`.`user_id` = 1 AND `likes`.`post_id` = 2 LIMIT 1 web_1 | ↳ app/controllers/likes_controller.rb:9:in `destroy' web_1 | (0.3ms) BEGIN web_1 | ↳ app/controllers/likes_controller.rb:9:in `destroy' web_1 | Like Destroy (0.7ms) DELETE FROM `likes` WHERE `likes`.`id` = 6 web_1 | ↳ app/controllers/likes_controller.rb:9:in `destroy' web_1 | (2.4ms) COMMIT web_1 | ↳ app/controllers/likes_controller.rb:9:in `destroy' web_1 | Rendering likes/destroy.js.erb web_1 | (0.7ms) SELECT COUNT(*) FROM `likes` WHERE `likes`.`post_id` = 2 web_1 | ↳ app/views/posts/_post.html.erb:3 web_1 | Like Exists? (0.9ms) SELECT 1 AS one FROM `likes` WHERE `likes`.`user_id` = 1 AND `likes`.`post_id` = 2 LIMIT 1 web_1 | ↳ app/models/user.rb:16:in `liked_by?' web_1 | Rendered posts/_post.html.erb (Duration: 10.5ms | Allocations: 1795) web_1 | Rendered likes/destroy.js.erb (Duration: 13.8ms | Allocations: 2045) web_1 | Completed 200 OK in 42ms (Views: 15.0ms | ActiveRecord: 7.1ms | Allocations: 6942)
#ソースコードを表示をした結果
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。