前提・実現したいこと
rails でユーザーごとにリンクを投稿し
投稿の詳細画面に非同期で「いいね機能」を作っています。
------------パターン1------------
投稿詳細画面を開く
ボタン状態:未いいね
↓ いいね押す(create実行後、レンダリング _goodのif)
ボタン状態:いいね済
↓ いいね押す(destroy実行後、レンダリング _goodのif)
ボタン状態:未いいね
↓
---------繰り返し---------
と正常に動作し、カウンターの数値もきちんと表示されています。
しかし、詳細画面を開いた時にいいね済状態の場合
-----------------------------パターン2------------------------------
投稿詳細画面を開く
ボタン状態:いいね済
↓ いいね押す(destroy実行後、レンダリング _goodのif)
ボタン状態:未いいね
↓ いいね押す(??POSTではなくDELETEが実行されている??)
------------エラー発生 ボタン状態:未いいね なにも起きない------------
このように挙動がないので
再読み込みをしたら 未いいね状態 その後の動作は パターン1
その後も、詳細画面を いいね済 で開いたら パターン2 となり
ログを確認したら destroyのメソッドエラーとなっていました。
発生している問題・エラーメッセージ
エラーメッセージ NoMethodError (undefined method `destroy' for nil:NilClass): app/controllers/goods_controller.rb:12:in `destroy'
NoMethodError in GoodsController#destroy undefined method `destroy' for nil:NilClass Extracted source (around line #12): #10 def destroy #11 @good = Good.find_by(user_id: current_user.id, post_id: params[:post_id]) *12 @good.destroy #13 #14 @post.reload #15 end Extracted source (around line #6): #4 module BasicImplicitRender # :nodoc: #5 def send_action(method, *args) *6 super.tap { default_render unless performed? } #7 end #8 #9 def default_render(*args) Extracted source (around line #194): #192 # which is *not* necessarily the same as the action name. #193 def process_action(method_name, *args) *194 send_action(method_name, *args) #195 end #196 #197 # Actually call the method associated with the action. Override Request parameters {"_method"=>"delete", "authenticity_token"=>"nyje1yH2NZ4xffO4HVpgb3D/rftrx9yPAxCMaMwx3zZVEStbpapgXuJwph4OfMTySB6RJJAuSvQE2hjjTYHdZQ==", "post_id"=>"9", "format"=>"286"} Session dump _csrf_token: "yjn1jIRcVcDTDVWmEyaknTjhPN/76ZZ7B8qUi4GwAlM=" session_id: "116c5a71c5f53de98fcb17f180645e5d" user_id: 1 Env dump GATEWAY_INTERFACE: "CGI/1.2" HTTP_ACCEPT: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01" HTTP_ACCEPT_ENCODING: "gzip, deflate, br" HTTP_ACCEPT_LANGUAGE: "ja,en-US;q=0.9,en;q=0.8" HTTP_ORIGIN: "http://localhost:3000" HTTP_VERSION: "HTTP/1.1" HTTP_X_CSRF_TOKEN: "nyje1yH2NZ4xffO4HVpgb3D/rftrx9yPAxCMaMwx3zZVEStbpapgXuJwph4OfMTySB6RJJAuSvQE2hjjTYHdZQ==" ORIGINAL_SCRIPT_NAME: "" REMOTE_ADDR: "::1" SERVER_NAME: "localhost" SERVER_PROTOCOL: "HTTP/1.1" Response headers None
routes.rb
ruby
1delete '/posts/:post_id/goods', to: 'goods#destroy', as: :good 2 3 resources :posts do 4 resources :goods 5 end
routes
good DELETE /posts/:post_id/goods(.:format) goods#destroy post_goods POST /posts/:post_id/goods(.:format) goods#create
model
good.rb
ruby
1class Good < ApplicationRecord 2 belongs_to :post, counter_cache: :goods_count 3 belongs_to :user 4end 5
post.rb
ruby
1has_many :goods, dependent: :destroy 2 def good_user(user_id) 3 goods.find_by(user_id: user_id) 4 end 5
###show.html.slim
slim
1= render partial: 'goods/good',locals: { post: @post , good: @good}
goods_controller
ruby
1class GoodsController < ApplicationController 2 before_action :good_setup 3 4 def create 5 Good.create(user_id: current_user.id, post_id: params[:post_id]) 6 7 @post.reload 8 end 9 10 def destroy 11 @good = Good.find_by(user_id: current_user.id, post_id: params[:post_id]) 12 @good.destroy 13 14 @post.reload 15 end 16 17 18 private 19 def good_setup 20 @post = Post.find(params[:post_id]) 21 end 22 23end 24
_good.html.slim
slim
1- if post.good_user(current_user.id) 2 = button_to good_path(post,good),method: :delete, id: 'good_buttons', remote: true do 3 = image_tag("no_good.jpg") 4 .nav.justify-content-center 5 ur 6 li = 'good' 7 li = post.goods_count 8- else 9 = button_to post_goods_path(post),method: :post,id: 'good_buttons', remote: true do 10 = image_tag("good.jpg") 11 .nav.justify-content-center 12 ur 13 li = 'good' 14 li = post.goods_count 15
###create.js.erb
$("#good_buttons").html("<%= j(render partial: 'good', locals: { post: @post,good: @good })%>");
###destroy.js.erb
$("#good_buttons").html("<%= j(render partial: 'good', locals: { post: @post,good: @good })%>");
試したこと
ルーティングのidがおかしいのかもしれないと調べてみるも
まだまだ勉強不足でどうしていいのかわからず
jsやAjaxに関しては全く触れたことがなかったのでハマっています。
create
の初動がないと
単純に@good.destroy
の current_user.id
が取得できていない?
jsの挙動のタイミングなどわからないことだらけで。。。
よろしければ、問題解決に繋がるような
参考サイト、書籍等または解決へのヒントをご教示願います。
補足情報(FW/ツールのバージョンなど)
ruby 2.5.3
Rails 5.2.3
gem 'slim-rails'
gem 'html2slim'
gem 'bootstrap'
gem 'jquery-rails'
gem 'jquery-turbolinks'
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。