LoginSignup
0
1

More than 5 years have passed since last update.

belongs_toについて学ぶ_100DaysOfCodeチャレンジ3日目(Day_3:#100DaysOfCode)

Last updated at Posted at 2018-06-18

はじめに

この記事はTwitterで人気のハッシュタグ#100DaysOfCodeをつけて、
100日間プログラミング学習を続けるチャレンジに挑戦した3日目の記録です。

動作環境

  • ruby 2.4.1
  • Rails 5.0.1

現在学習している内容のリポジトリ

本日学んだこと

  • モデル同士の関連付け(belongs_to)
  • belogns_toのオプションについて

関連付けについて

ContactモデルとKindモデルがあったとします。

contact-kind-relation.png

Contactテーブルにあるkind_idは外部キーとなっており、Kindテーブルのidを参照している状態。

そのため、Contactモデルが、以下のように定義されているとき、kind_idを指定しないとAPIなどでPOSTした際にエラーとなる。

# app/models/contact.rb
class Contact < ApplicationRecord
  belongs_to :kind
end

Postmanでkind_idを指定せずにPOSTすると、エラーとなり失敗してしまいます。。
contact-kind-relation-postman.png

コンソールで確認してみても、Rollbackが発生しているのが確認できますね。
contact-kind-relation-console.png

belongs_toのオプション

先ほどはkind_idを指定しないとエラーになると説明しましたが、実はoptional:trueにすればnullになるだけでエラーにはなりません。

PostmanでAPIに対してPOSTしてみると、kind_idはnullですがちゃんとリクエストが送れていますね。

contact-kind-relation-postman2.png

コンソールでもちゃんとcommitされているのがわかります。

Started POST "/contacts" for 127.0.0.1 at 2018-06-19 01:16:44 +0900
Processing by ContactsController#create as */*
  Parameters: {"name"=>"Yuta-Ushijima", "email"=>"sample@test.com", "contact"=>{"name"=>"Yuta-Ushijima", "email"=>"sample@test.com"}}
   (0.1ms)  begin transaction
  SQL (3.4ms)  INSERT INTO "contacts" ("name", "email", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["name", "Yuta-Ushijima"], ["email", "sample@test.com"], ["created_at", "2018-06-18 16:16:45.343412"], ["updated_at", "2018-06-18 16:16:45.343412"]]
   (5.5ms)  commit transaction
Completed 201 Created in 152ms (Views: 14.7ms | ActiveRecord: 26.0ms)

関連付けをしたらstrong_paramsの設定を忘れずに

それではここで、kind_idを指定して改めてPOSTしてみます。

contact-kind-relation-postman3.png

おや、しっかりとkind_idを指定しているのに、kind: must existとなっていますね。

なぜでしょうか。

実はこれ、strong_paramsの設定において、kind_idのパラメータが送られてくることを許可していないことが原因なのです。

コンソールで確認してみると、Unpermitted parameter: kind_idとなっています。

Started POST "/contacts" for 127.0.0.1 at 2018-06-19 01:20:26 +0900
Processing by ContactsController#create as */*
  Parameters: {"name"=>"Yuta-Ushijima", "email"=>"sample@test.com", "kind_id"=>2, "contact"=>{"name"=>"Yuta-Ushijima", "email"=>"sample@test.com", "kind_id"=>2}}
Unpermitted parameter: kind_id
   (0.3ms)  begin transaction
   (0.1ms)  rollback transaction
Completed 422 Unprocessable Entity in 93ms (Views: 0.9ms | ActiveRecord: 20.1ms)

この問題を解消するには、strong_paramsの設定をしているcontacts_controller.rbを変更してあげればOK。

現在の設定

class ContactsController < ApplicationController

  ## 中略 

  private
    # Only allow a trusted parameter "white list" through.
    def contact_params
      params.require(:contact).permit(:name, :email, :birthdate)
    end
end

permitの引数にシンボルで:name, :email, :birthdayを渡していますね。

ここの箇所に:kind_idのように渡してあげれば、問題なくPOSTできるようになるはずです。

変更後

class ContactsController < ApplicationController

  ## 中略 

  private
    # Only allow a trusted parameter "white list" through.
    def contact_params
      params.require(:contact).permit(:name, :email, :birthdate, :kind_id)
    end
end

コンソールでもきちんとcommitされているのがわかります。

Started POST "/contacts" for 127.0.0.1 at 2018-06-19 01:34:04 +0900
Processing by ContactsController#create as */*
  Parameters: {"name"=>"Yuta-Ushijima", "email"=>"sample@test.com", "kind_id"=>2, "contact"=>{"name"=>"Yuta-Ushijima", "email"=>"sample@test.com", "kind_id"=>2}}
   (0.1ms)  begin transaction
  Kind Load (7.3ms)  SELECT  "kinds".* FROM "kinds" WHERE "kinds"."id" = ? LIMIT ?  [["id", 2], ["LIMIT", 1]]
  SQL (4.6ms)  INSERT INTO "contacts" ("name", "email", "created_at", "updated_at", "kind_id") VALUES (?, ?, ?, ?, ?)  [["name", "Yuta-Ushijima"], ["email", "sample@test.com"], ["created_at", "2018-06-18 16:34:05.078798"], ["updated_at", "2018-06-18 16:34:05.078798"], ["kind_id", 2]]
   (6.5ms)  commit transaction
Completed 201 Created in 142ms (Views: 3.5ms | ActiveRecord: 30.4ms)
0
1
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
0
1