LoginSignup
7
8

More than 3 years have passed since last update.

[Ruby on Rails] 他のテーブルを参照してidを取得し、外部キーとしてデータを挿入する

Last updated at Posted at 2019-12-15

実現したい事

データを挿入するテーブルとは別のテーブルの情報を参照して、該当するデータのidを外部キーとして、元のテーブルにデータを追加する
スクリーンショット 2019-12-15 17.32.24.png

前提

テーブルは生産量のデータを持つProductions(生産量)テーブルと製品の情報を持つItems(製品)テーブルがあります。Productionsモデルには、idとamount(生産量)、Itemsテーブルと紐づけるためのItem_idを持っています。Itemsテーブルにはidとcode(製品コード)とname(製品名)のカラムを持ちます。また、Goodsテーブルにはすでに、製品の情報が入っているものとします。

今しようとしている事

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

方法

まずはフォームは簡単にこのようになっています。

index.html
<%= form_for [@production], url: productions_path do |f| %>
  <%= f.text_field :amount %>
  <%= f.text_field :good_id  %>
  <%= f.submit '追加' %>
<% end %>

そして、コントローラのcreateアクションを以下のように書きます。

controller/productions_controller.rb
class ProductionsController < ApplicationController
  def create
    item_id = Item.find_by(code: params[:production][:item_id]).id
    Production.create(production_params.merge(item_id: item_id))
  end

  private
  def production_params
    params.require(:production).permit(:amount)
  end
end

permitではamountだけを許可して、createアクション内で、find_byを用いて、item_id = Item.find_by(code: params[:production][:item_id]).idと記述し、Itemテーブルでデータを探して、item_idに入れ直しています。
そして、createアクションをする際に、item_idをmergeする事で外部キーとしてidの値を挿入することができました。

注意点

フォームで、form_forを使っているので、値を渡すときはparams[:production][:item_id]と書きましょう。params[:item_id]と書くと、値が渡せず、エラーになります。

補足情報

Rails 5.0.7.2
ruby 2.5.1

7
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
8