中間テーブルとは　〜DB設計〜

#概要

アソシエーションの中で多対多の関係性で使われる中間テーブル。

今回、中間テーブルとは何か？　自分の復習用に記事を執筆しようと思います。

##そもそもアソシエーションとは？

Railsで使われているテーブルとテーブルを関連づける機能。

例えば、TwitterではUserとtweetがあるとして、

二つはUserがtweetすることでtweetが生じる関連付いた関係性である。

###アソシエーションを組まないとどうなるのか？

**AさんがtweetしたtweetがAさんと関連づけされなくなる。**

AさんのtweetもBさんのtweetも一緒くたに扱われるため、外部キーのIDを取得する必要が出てきます。


###一対多、一対一の関係性

アソシエーションの中には一対多、一対一

**最後に中間テーブルが使われる多対多の関係性が存在する。**

####一対多

最初に一対多とは親モデルが子モデルに対して多数の要素を持つこと。

Twitterの場合、一つのUser（親モデル）は沢山のtweet(子モデル）をします。



Userモデル（親モデル）

| ID       |       Username | 
|:-----------------|------------------|
| 1             |              tarou | 
| 2           |            jirou | 
| 3             |              saburou | 
| 4               |                sirou |
| 5             |             gorou |


Tweetモデル（子モデル）

| ID       |       User_id |    text    |
|:-----------------|------------------|------------------|
| 1            |              1 |        あいうえお        |
| 1            |              1 |        たろうです        |
| 2           |            2 |       かきくけこ     |
| 3             |              3 |        さしすせそ        |
| 4               |                4 |         たちつてと        |
| 5             |             5 |       なにぬねの       |


railsでUserモデル(親モデル）に

```ruby:User.rb
has_many :tweet
```

has_manyの記述を加えます。
 
Tweetモデル（子モデル）に

```ruby:Tweet.rb
belongs_to :user
```

belongs_toの記述を加えます。


####一対一

一対一は関連するモデルの立場が対等です。

Userモデル

| ID       |       Username | 
|:-----------------|------------------|
| 1             |              tarou | 
| 2           |            jirou | 
| 3             |              saburou | 
| 4               |                sirou |
| 5             |             gorou |

Profileモデル

| ID       |       User_id |    text    |
|:-----------------|------------------|------------------|
| 1            |              1 |        よろしく        |
| 2           |            2 |       じろうです     |
| 3             |              3 |        さぶろうです        |
| 4               |                4 |         しろうです        |
| 5             |             5 |       ごろうです       |


Userモデルに対するProfileといった具合に同等の関係を示す場合に使われます。

railsでUserモデル(親モデル）に

```ruby:User.rb
has_one :profile
```

has_oneの記述を加えます。

Profileモデル（子モデル）に

```ruby:Tweet.rb
belongs_to :user
```

belongs_toの記述を加えます。


###中間テーブルとは？

二つのモデルが多対多の関係性の時に使われるモデル。

ChatアプリのDB設計をする際、UserモデルとGroupモデルがあるとします。

Userは複数のチャットGroupに属し、チャットGroupも複数のUserが所属している。

この場合、中間テーブルが必要になってきます。


####なんで中間テーブルを使う必要があるの？

例えば、Userが1と3のChatグループに属していたとします。

中間テーブルを挟まない場合、Groupに所属することを示すカラムが2つ必要になります。

Userが1と2と３のChatグループに属していたら、3つのカラムが必要になります。

際限なくカラムが多くなってくるので、それを防ぐために中間テーブルが必要になります。

Memberモデル（中間テーブル）

| ID       |       User_id |    group_id    |
|:-----------------|------------------|------------------|
| 1            |              1 |        1       |
| 2           |            1|       2     |
| 3             |              2|        1        |
| 4               |                2 |         3        |
| 5             |             3 |      2       |


この様に中間テーブルを挟むことでカラムを増やす必要がなくなります。

```ruby:User.rb
has_many :group, through: :member
```

```ruby:group.rb
has_many :user, through: :member
```

モデルファイルに以上の記述を行えば、多対多のアソシエーションが設定されます。