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

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

## 動作環境
* ruby 2.4.1
* Rails 5.0.1

## 現在学習している内容のリポジトリ
https://github.com/yuta-ushijima/notebook-api-on-rails

## 本日学んだこと

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

## 関連付けについて

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

![contact-kind-relation.png](https://qiita-image-store.s3.amazonaws.com/0/195539/80a50a6e-d318-89b7-6b97-0aa0ca66307f.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](https://qiita-image-store.s3.amazonaws.com/0/195539/aee2e4a4-f8f5-e228-b49f-8d9ba2df5499.png)

コンソールで確認してみても、Rollbackが発生しているのが確認できますね。
![contact-kind-relation-console.png](https://qiita-image-store.s3.amazonaws.com/0/195539/2568b733-c68c-064f-4e98-f6db7e9e1917.png)

## belongs_toのオプション

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

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

![contact-kind-relation-postman2.png](https://qiita-image-store.s3.amazonaws.com/0/195539/1fb46cec-9055-117d-1925-92be001a573d.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](https://qiita-image-store.s3.amazonaws.com/0/195539/5a51c010-d3c0-d315-59da-0e4edf0c59be.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)
```