質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

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

Ruby on Rails 6

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

Q&A

解決済

1回答

1543閲覧

【Rails】お気に入りに追加した投稿が保存されない

kumamin

総合スコア12

Ruby

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

Ruby on Rails 6

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

0グッド

0クリップ

投稿2020/09/11 08:56

前提・実現したいこと

今、Ruby on Railsで投稿に対するお気に入り(いいね)機能を実装しています。

実現したいこととしては、投稿の詳細ページにあるお気に入りのアイコンをクリックするとそのユーザーのお気に入りの投稿に追加され、
もう一度クリックするとお気に入りの投稿から外れるといった、ごく一般的なお気に入り機能を実装したいです。

そこで、以下のQiita記事の「Favoriteの実装(多対多)」を参考にし、コードを書きました。
【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】

前提として、ここでは投稿をpost_g、お気に入りをfavoriteと定義しています。
また、今回の問題に関係あるかわかりませんが、UserモデルやPostGモデルにおいて、
投稿をしたユーザーをgiver、投稿に申し込むユーザーをtaker
ユーザーが投稿した投稿をgiving_post_gs、ユーザーが申し込んだ投稿をtaking_post_gsと定義しています。

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

発生している問題としては、お気に入りのアイコンをクリックしてもお気に入りが保存されないということです。
その原因を探るため、favorite_gs_controller.rbのcreateアクション内でcreate!と記述したところ、以下のエラーが出ました。

ActiveRecord::RecordInvalid in FavoriteGsController#create バリデーションに失敗しました: Post gを入力してください。

イメージ説明

該当のソースコード

▼routes.rb

ruby

1Rails.application.routes.draw do 2 3 resources :posts_g do 4 resource :favorite_gs, only: [:create, :destroy] 5 end 6 7end

▼posts_g_controller.rb

ruby

1class PostsGController < ApplicationController 2 3 def show 4 @user = @post.giver 5 @post = PostG.find(params[:id]) 6 @user = @post.giver 7 @favorite = @post.favorite_gs.where(user_id: current_user.id) 8 end 9 10end

▼views/posts_g/show.html.haml

haml

1 .Post_main__Box 2 - unless user_signed_in? && @user.id == current_user.id 3 - if @favorite.empty? 4 = link_to posts_g_favorite_gs_path(@post.id), method: :post do 5 = icon('far', 'bookmark', class: "Post_bookmark") 6 - else 7 = link_to posts_g_favorite_cs_path(@post.id), method: :delete do 8 = icon('fas', 'bookmark', class: "Post_bookmark")

▼favorite_gs_controller.rb

ruby

1class FavoriteGsController < ApplicationController 2 def create 3 FavoriteG.create!(user_id: current_user.id, post_g_id: params[:post_g_id]) 4 redirect_to posts_g_path(params[:posts_g_id]) 5 end 6 7 def destroy 8 favorite = FavoriteG.find_by(post_g_id: params[:post_g_id], user_id: current_user.id) 9 favorite.destroy 10 redirect_to posts_g_path(params[:posts_g_id]) 11 end 12end

▼favorite_g.rb

ruby

1class FavoriteG < ApplicationRecord 2 belongs_to :user 3 belongs_to :post_g 4 validates_uniqueness_of :post_g_id, scope: :user_id 5end

▼user.rb

ruby

1class User < ApplicationRecord 2 3 has_many :giving_post_gs, foreign_key: "giver_id", class_name: "PostG", dependent: :destroy 4 5 has_many :post_g_takers, foreign_key: "taker_id", dependent: :destroy 6 has_many :taking_post_gs, through: :post_g_takers, source: :taking_post_g, dependent: :destroy 7 8 has_many :favorite_gs, dependent: :destroy 9 10end

▼post_g.rb

ruby

1class PostG < ApplicationRecord 2 3 belongs_to :giver, class_name: 'User', foreign_key: 'giver_id' 4 has_many :post_g_takers, dependent: :destroy 5 has_many :takers, through: :post_g_takers, dependent: :destroy 6 7 has_many :favorite_gs, dependent: :destroy 8 9end

▼schema.rb

ruby

1 create_table "favorite_gs", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t| 2 t.integer "user_id" 3 t.integer "post_g_id" 4 t.datetime "created_at", precision: 6, null: false 5 t.datetime "updated_at", precision: 6, null: false 6 end

試したこと

  • paramsが送られていないのではないかと思い、エラー画面を確認するとparametersの中に"post_g_id"=>"13"ときちんと書かれていました。

  • モデルの書き方が間違っているのかと思い、Qiitaの記事を見直してみましたが、間違いがわかりませんでした。

  • favorite_g.rbbelongs_to :post_gの行にoptional: trueを追加してみたらエラー画面は出なくなったのですが、favorite_gsテーブルにpost_g_idが空の状態で保存されるようになってしまいました。

補足情報(FW/ツールのバージョンなど)

Railsのバージョンは6.0.3.2です。
データベースはMySQL、ユーザー機能はdeviseを使っています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

エラーの画像では、パラメータは"posts_g_id"=>"13"(複数形)になっています、
params[:post_g_id](単数形)なので受け取れていないかと思います。
単数形で取得うるのが正しいのでpathが間違えていたりするかもしれません。

また、こういう時はデバッグとして、
createアクションにbinding.irbを追記してparams[:post_g_id]が取得できるか、などを調べると良いです。

投稿2020/09/11 09:41

necocoa

総合スコア209

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

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

kumamin

2020/09/11 12:43

おかげさまで、無事解決できました。 複数形か単数形かというところには全く意識が届いていなかったので、大変助かりました。 いつもありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問