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

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

詳細はこちら
参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

Ruby

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

Ruby on Rails

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

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

Q&A

解決済

1回答

6306閲覧

[Ruby on Rails]外部のモデルの情報を参照してidを取得し、外部キーとしてデータを挿入したい

clora

総合スコア72

参照

参照は、プログラミングにおいて変数や関数といったメモリ空間上での所在を指示するデータのことを指します。その中にはデータ自体は含まれず、他の場所にある情報を間接的に指示するプログラムです。

Ruby

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

Ruby on Rails

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

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

0グッド

0クリップ

投稿2019/12/06 04:09

編集2019/12/06 05:42

前提

railsを使ってアプリを作成しています。
生産量と製品コードを入力すると、生産量とコードから参照された製品の情報を表示できるようにしたいと思っています。

モデルは生産量のデータを持つProductions(生産量)モデルと製品の情報を持つGoods(製品)モデルがあります。Productionsモデルには、idとamount(生産量)、Goodsの情報を参照するためにの外部キーであるgood_idのカラムを持っています。Goodsモデルにはidとcode(製品コード)とname(製品名)のカラムを持ちます。また、Goodsモデルにはすでに、製品の情報が入っているものとします。

今、Productionsコントローラのcreateアクションで、Prodectionsモデルに生産量と製品情報を入力しようとしています。
フォームではamount(生産量)とGoodsモデルのcodeの値を入力する形になっています(フォームでは、nameをgood_idとしています)。
この時、amount(生産量)はそのままProductionsモデルに追加できますが、good_idは外部キーなのでそのまま入力できません。なので、入力された値からGoodsモデルのcode情報を参照して、GoodsのidをProductionsのgood_idに追加したいです。
今のままですと、当然、good_idは外部キーなので、データを挿入できませんとエラーになります。

どのようにすれば、外部のモデルを参照して、該当するidを外部キーに挿入できるのでしょうか。
よろしくお願いします。
イメージ説明

実現したいこと

入力されたコードからGoodsモデルを参照して、該当するidをProductionsモデルのgood_idに挿入する

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

ActiveRecord::InvalidForeignKey in ProductionsController#create Mysql2::Error: Cannot add or update a child row: a foreign key constraint fails (`app_development`.`productions`, CONSTRAINT `fk_rails_da7ae25ed8` FOREIGN KEY (`good_id`) REFERENCES `goods` (`id`)): INSERT INTO `productions` (`good_id`, `created_at`, `updated_at`) VALUES (11111, '2019-12-06 03:18:18', '2019-12-06 03:18:18')

該当のソースコード

ruby

1#controller/productions_controller.rb 2class ProductionsController < ApplicationController 3 def index 4 @production = Production.new 5 end 6 7 def create 8 Production.create(production_params) 9 end 10 11 private 12 def production_params 13 params.require(:production).permit(:amount, :goods_id) 14 end 15end

ruby

1#models/production.rb 2class Production < ApplicationRecord 3 belongs_to :good 4end 5 6#models/good.rb 7class Good < ApplicationRecord 8 has_many :productions 9end

html

1#productions/index.html 2<%= form_for [@production], url: productions_path do |f| %> 3 <div class="form__info__date"> 4 <div class="form__info__date__amount"> 5 <%= f.text_field :amount %> 6 </div> 7 <div class="form__info__date__id"> 8 <%= f.text_field :good_id %> 9 </div> 10 <div class="form__info__date__btn"> 11 <%= f.submit 'send', class: "btn" %> 12 </div> 13 </div> 14<% end %>

試したこと

https://teratail.com/questions/100899
このページを参考にfind_byを使って下記のようなコードをparamsのpermit中に記述してみたりしたのですが、syntax errorとなってしまいます。
コードが間違っているのでしょうか。それとも、記述する位置が違うのでしょうか。

ruby

1#controller/productions_controller.rb 2good_id: Good.find_by(code: [:good_id]).id

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

Rails 5.0.7.2
ruby 2.5.1

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

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

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

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

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

guest

回答1

0

ベストアンサー

permitでは code以外を許可します
で、
create内で good_id = Good.find_by(code: [:good_id]).id
しておいて
Production.create(production_params.merge( good_id: good_id))
としてみてください

投稿2019/12/06 04:17

winterboum

総合スコア23567

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

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

clora

2019/12/06 05:09

迅速な回答ありがとうございます。 言われた通り記述してみました。 def create good_id = Good.find_by(code: [:good_id]).id Production.create(production_params) end しかし、 undefined method `id' for nil:NilClass とエラーが出てしまいました。おそらく、[:good_id]の中が空っぽなのではと考えました。 ターミナルを確認すると、値は確かにgood_idに入っています。しかし、form_forでフォームを作成しているので、ハッシュが二重構造?になっているために、取り出せないのではないかと思いました。 ↓ターミナル上 Processing by ProductionsController#create as HTML Parameters: {"utf8"=>"✓",~省略~, "production"=>{"amount"=>"20", "good_id"=>"2222"}, "commit"=>"送信"} なので、 product_id = Product.find_by(code: params[:production][:good_id]).id と書き直してみたところ、うまくいきました!!!! 迅速な対応ありがとうございました!!!!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問