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

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

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

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

2回答

2673閲覧

rails DB登録 ActiveRecord::AssociationTypeMismatch in FriendsController#create

tomato185

総合スコア29

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2020/11/16 23:33

編集2020/11/16 23:45

###実現したいこと
friendsテーブルにデータを登録させたい。(フォロー機能)

###現状
users↔︎friends↔︎farmers
というように、usersとfarmersはN対Nにしております。

###エラー箇所

ActiveRecord::AssociationTypeMismatch in FriendsController#create User(#70277525473660) expected, got "2" which is an instance of String(#70277522570720)
class FriendsController < ApplicationController def create @friend = Friend.new(friend_params)★ここ!! if @friend.save! redirect_to farmer_path(friend_params[:farmer]) else

エラー文は、Userの外部キーがほしいのにもってきたパラメータがStringなのでダメ!と怒られていると解釈しているのですが、viewから送ったのは、value: current_userで数字ではないのかな??と悩んでおります。

###該当コード

popularsの段階では売り上げ順になっているが、その後はただの商品id順になってしまう。。。 (show.html.erb) <div class="follow_area"> <%= form_for(Friend.new, url: friends_path, html: {class: "follow_farmer"}) do |f|%> <%= f.hidden_field :user, value: current_user.id %> <%= f.hidden_field :farmer, value: params[:id] %> <%= f.submit "フォローする", class:"follow_btn"%> <% end %> </div>
(friends_controller.rb) class FriendsController < ApplicationController def create @friend = Friend.new(friend_params) if @friend.save! redirect_to farmer_path(friend_params[:farmer]) else redirect_to farmer_path(friend_params[:farmer]) end end def destroy end private def friend_params params.require(:friend).permit(:user, :farmer) end end
モデル: farmer.rb has_many :friends, dependent: :destroy
モデル: friend.rb class Friend < ApplicationRecord belongs_to :user belongs_to :farmer end
モデル: user.rb has_many :friends, dependent: :destroy
Friendsテーブル class CreateFriends < ActiveRecord::Migration[5.2] def change create_table :friends do |t| t.references :user, foreign_key: true t.references :farmer, foreign_key: true t.timestamps end end end

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

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

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

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

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

guest

回答2

0

回答とは異なりますが、
悪意のあるユーザーがparams.user(user_id)の値を改変して送信すると
任意のユーザーにフォローさせてしまえませんか

user(user_id) の値はフォームに埋め込むのではなく、
コントローラーのcurrent_user.idから持ってきた方が良いと思います

投稿2020/11/16 23:58

neko_daisuki

総合スコア2090

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

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

tomato185

2020/11/17 12:25

neko_daisuki様 ご指摘ありがとうございます! params.user(user_id)の値というのはストロングパラメーターに、ということでしょうか?
neko_daisuki

2020/11/17 13:07

viewの以下の部分です <%= f.hidden_field :user_id, value: current_user.id %> 攻撃者はこの値を自由に書き換えられます ストロングパラメーターは更新されるカラムを限定するものですが、値は守ってくれません
tomato185

2020/11/17 22:48

ご回答ありがとうございます。 確かにそうですね! 実際に、値を守るようにするなら、どのように記述すればよろしいでしょうか。 当方、現在勉強中で、「user(user_id) の値はフォームに埋め込むのではなく、」 の意味が理解できておりません。 もしよろしくければ教えていただけると幸いです。
neko_daisuki

2020/11/19 14:52

取得したい値は current_user.id です。 この値は、いまログインしているユーザーのIDなのですから、 ユーザーにフォームから送信させるまでもなく、コントローラーから取得可能なはずです。 def friend_params params.require(:friend).permit( :farmer_id).merge(user_id: current_user.id) end 今の実装では、以下の操作で(ログインしている)自分以外のユーザーにフォローさせることが出来てしまいます。 1.show.html.erbを開きます。 2.デベロッパーツールを開きます。 3.Elements から <input type="hidden" name="user_id" value="x">を探します 4.valueの値を他のユーザーのIDに書き換えてフォローボタンを押します (farmer_idを書き換えることもできます)
tomato185

2020/11/19 23:50

ありがとうございます! mergeメソッドは初知りでした! 使用方法までありがとうございます、今後はmergeメソッドが使えるところは 使用していきます。 ありがとうございました。
guest

0

自己解決

<%= f.hidden_field :user, value: current_user.id %> <%= f.hidden_field :farmer, value: params[:id] %>

でカラム名をuser/farmerとそれぞれしているが、そもそもfriendsテーブルにはuser_id/farmer_idになっているから、、、、

<%= f.hidden_field :user_id, value: current_user.id %> <%= f.hidden_field :farmer_id, value: params[:id] %>

にしたら良い。
なので、ストロングパラメーターも併せて変更したら良い。

投稿2020/11/16 23:50

tomato185

総合スコア29

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問