🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

1回答

806閲覧

中間テーブル(お気に入り)のdestroyアクションで中間テーブルのidを渡せず困っております。

kazuuuuma

総合スコア1

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2021/02/23 13:56

前提・実現したいこと

中間テーブル(favorites)を使ってpostのお気に入り登録と登録したもののお気に入り削除できる機能を実装しております。
お気に入りの登録はできたのですが、削除についてはfavorites#destroyアクションのパスでも削除がうまくいきません。
お気に入り登録された特定のpostの削除になるので、中間テーブルのidが必要になると思うのですが、どうしてもdestroyアクションのパスに渡せず、エラーになってしまいます。
どのように、中間テーブルの idをdestroyアクションに渡せば良いでしょうか。
初歩的な質問かと思いますが、アドバイスいただければ幸いです。

発生している問題・エラーメッセージ

ActionController::UrlGenerationError in Posts#index
Showing /Users/k.h/projects/we-camp/app/views/favorites/_favorite.html.erb where line #3 raised:

No route matches {:action=>"destroy", :controller=>"favorites", :id=>nil, :post_id=>"1"}, missing required keys: [:id]

######エラー箇所

<% if user_signed_in? %> <% if post.favorited_by?(current_user) %> #エラー箇所↓ <%= link_to post_favorite_path(post,@favorite), method: :delete, remote: :true do %> <button type="button" class="btn btn-light"> <h2><i class="fa fa-star" aria-hidden="true"></i><%= post.favorites.count %></h2> </button>

ソースコード

######favorites_controller.rb

class FavoritesController < ApplicationController before_action :set_post before_action :authenticate_user! def create if @post.user_id != current_user.id favorite = current_user.favorites.build(post_id: params[:post_id]) favorite.save redirect_to post_path end end def destroy #@favorite = Favorite.find(params[:id]) @favorite = Favorite.find(id: params[:id], user_id: currrent_user.id, post_id: params[:post_id]) @favorite.destroy redirect_to post_path end private def set_post @post = Post.find(params[:post_id]) end end

######posts/index.html.erb

<%= render "shared/header" %> <%# /検索 %> <%= form_with(url: search_posts_path, local: true, method: :get, class: "search-form") do |form| %> <%= form.text_field :keyword, placeholder: "検索", class: "search-input" %> <%= form.submit "検索", class: "search-btn" %> <% end %> <%# /投稿一覧 %> <div class="row"> <% @posts.each do |post| %> <div class="col-8"> <div class="card"> <div class="card-body"> <h4 class="card-title"> <%= link_to post.campsite, "#", method: :get %> </h4> </div> <%= link_to post_path(post.id), method: :get do %> <%= image_tag post.image, class: "img-fluid" %> <% end %> <div class="card-body"> <h5 class="card-subtitle"><%= link_to post.user.nickname, "/users/#{post.user_id}", method: :get %></h5> <div id="favorites_buttons_<%= post.id %>"> <%= render partial: 'favorites/favorite', locals: { post: post} %> </div> <h5 class="card-text"><%= post.text %></h5> </div> </div> </div> <% end%> </div>

######favorites/_favorite.html.erb

<% if user_signed_in? %> <% if post.favorited_by?(current_user) %> <%= link_to post_favorite_path(post,@favorite), method: :delete, remote: :true do %> <button type="button" class="btn btn-light"> <h2><i class="fa fa-star" aria-hidden="true"></i><%= post.favorites.count %></h2> </button> <% end %> <% else %> <%= link_to post_favorites_path(post.id), method: :post, remote: :true do %> <button type="button" class="btn btn-light"> <h2><i class="fa fa-star-o" aria-hidden="true"></i><%= post.favorites.count %></h2> </button> <% end %> <% end %> <% else %> <button type="button" class="btn btn-light"> <h2><i class="fa fa-star" aria-hidden="true"></i><%= post.favorites.count %></h2> </button> <% end %>

######routes.rb

Rails.application.routes.draw do devise_for :users root to:"posts#index" resources :user resources :posts do collection do get 'search' end resources :favorites, only: [:create, :destroy, :index] resources :reviews, only: [:create, :destroy] end end

ご教授いただければ幸いでございます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

post_favorite_path(post,@favorite) で突然 @favoriteが出てくるので、nil になります。
階層routeしてるので、favoriteを特定せんとならなくなってますね。
favorite = post.favorites.find_by(user_id: current_user.id)
とか
favorite = current_user.favorites.find_by(post_id: post.id)
とか。
ただ、これをviewには書きたくないな。
Post か User に def favorite_of(user)とかdef favorite_for(post)とか作っておき post_favorite_path(post,post.favorite_of(current_user))みたいにするのを薦めます。
Favorite に 作っても良いけど。

投稿2021/02/23 23:14

winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuuuuma

2021/02/24 10:30

回答いただきありがとうございます! favoriteを特定しなければならないのですね! 分かりやすく回答いただきありがとうございました。 一つお聞きしたいのですが、 postモデルで下記教えていただきましたメソッドのところでエラーが出てしまいました。 def favorite_of(user) favorite = post.favorites.find_by(user_id: current_user.id) end エラー文 undefined local variable or method `post' for #<Post:0x00007f8e69fdbb38> ここのpostはなぜ定義されていないと判断されてしまうのでしょうか? ご教授いただければ幸いです。
winterboum

2021/02/24 10:46

Post model に書くときは  favorite = favorites.find_by(user_id: user.id)
kazuuuuma

2021/02/24 12:06

ありがとうございます! 無事削除機能実装できました! ご丁寧に教えていただきありがとうございました。 また機会があればよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問