前提・実現したいこと
実現したいことはいいねを押したらその場でいいねボタンの表示が切り替わるようにしたいです。
いいね機能をAjaxで実装したいのですがredirect_toの記述をコメントアウトすると下記のようなエラーがターミナル上で出てしまいます。手動でブラウザの更新をするといいねの表示やDBに記録はされるのですが更新をしないといけません。また今はコメントアウトしているredirect_toの記述をlike_controller.rbで追加している場合には非同期通信になっていて更新はされないが、一番上に行ってしまいます。どこかおかしな記述があればご指摘していただきたく今回投稿しております。よろしくお願いいたします。
足りない情報などがございましたら教えてくれたら幸いです。
発生している問題・エラーメッセージ
ターミナル ActionView::Template::Error (undefined method `id' for nil:NilClass): 1: <% if Like.find_by(user_id: current_user.id, idea_id: @idea.id) %> 2: <%= link_to (idea_like_path(@idea.id)), method: :delete, id: "like-button", remote: true do %> 3: <span class="fa fa-heart like-btn-unlike"></span> 4: <%= @likes_count %>
該当のソースコード
shared/_like.html.erb
<% if Like.find_by(user_id: current_user.id, idea_id: @idea.id) %> <%= link_to (idea_like_path(@idea.id)), method: :delete, id: "like-button", remote: true do %> <span class="fa fa-heart like-btn-unlike"></span> <%= @likes_count %> <% end %> <% else %> <%= link_to (idea_likes_path(@idea.id)), method: :post, id: "like-button", remote: true do %> <span class="fa fa-heart like-btn"></span> <%= @likes_count %> <% end %> <% end %>
like_controller.rb
class LikesController < ApplicationController def create @like = Like.new(user_id: current_user.id, idea_id: params[:idea_id]) @like.save # redirect_to("/ideas/#{params[:idea_id]}") ここをコメントアウトしています。 end def destroy @like = Like.find_by(user_id: current_user.id, idea_id: params[:idea_id]) @like.destroy # redirect_to("/ideas/#{params[:idea_id]}") ここをコメントアウトしています。 end end
likes/create.js.erb
$('.fa fa-heart like-btn').append("<%= escape_javascript(render 'shared/like', locals: { idea: @idea }) %>");
###likes/destroy.js.erb
$('.fa fa-heart like-btn-unlike').append("<%= escape_javascript(render 'shared/like', locals: { idea: @idea }) %>");
###ideas_controller.rb
class IdeasController < ApplicationController before_action :login_check, only: [:new, :show] def index @ranks = Idea.order('likes_count DESC').limit(3) @novelties = Idea.order('created_at DESC').limit(3) end def new @idea = Idea.new end def create @idea = Idea.new(idea_params) if @idea.save redirect_to root_path else render :new end end def show @idea = Idea.find(params[:id]) @likes_count = Like.where(idea_id: @idea.id).count @comment = Comment.new @comments = @idea.comments.includes(:user) end def edit @idea = Idea.find(params[:id]) end def update @idea = Idea.find(params[:id]) if @idea.update(idea_params) redirect_to ideas_path else render :edit end end def destroy @idea = Idea.find(params[:id]) if @idea.destroy redirect_to ideas_path else render :show end end private def idea_params params.require(:idea).permit(:genre_id, :image, :title, :content).merge(user_id: current_user.id) end def message_params params.require(:idea).permit(:image, :title).merge(user_id: current_user.id) end # ログインしていない場合登録画面に遷移する def login_check unless user_signed_in? flash[:alert] = 'ログインしてください' redirect_to new_user_session_path end end end
show.html.erb
<div class="show"> <div class="idea-show"> <div class="idea-title"> <h1 class="title"> <%= @idea.title %> </h1> </div> <div class="idea-img"> <%= image_tag @idea.image, class: "idea-image" if @idea.image.attached? %> </div> <div class="idea-content"> <%= @idea.content %> </div> <%= render 'shared/like', locals: { idea: @idea, like: @like } %> </div> </div>
###routes.rb
Rails.application.routes.draw do devise_for :users root to: "ideas#index" resources :ideas do resources :likes, only: [:create, :destroy] resources :comments, only: :create end end
補足情報(FW/ツールのバージョンなど)
rails6
mysql2
あなたの回答
tips
プレビュー