エンジニア転職日記

エンジニア転職に向けての日記です

DM機能の実装(DB設計)

概要

オリジナルアプリの基本的な実装が完了したので、DM機能の追加に入っています。

作成中のアプリについての概要はこちらから。

 

shangang7321.hatenablog.com

 

DB設計

まずは、エンティティの洗い出しから行います。DM機能の実装には大きく分けて3つの要素があります。

・ユーザー管理機能

・チャットルーム機能

・メッセージ管理機能

これらの機能に必要なテーブルは

・usersテーブル

・roomsテーブル

・messagesテーブル

の3つです。各テーブルごとに必要なカラム情報は、以下の通りです。

usersテーブル

・name

・email

・password

roomsテーブル

・name

messagesテーブル

・content

・image

・created_at

・room_id

・user_id

 

次は、テーブル間の関係性を考えていきます。

usersテーブルとmessagesテーブル

1人のユーザーは複数のメッセージを持つ(一対多)

roomsテーブルとmessagesテーブル

1つのチャットルームは複数のメッセージを持つ(一対多)

usersテーブルとroomsテーブル

1人のユーザーは複数のチャットルームに属し、1つのチャットルームは複数のユーザーを持つ(多対多)

多対多の関係性を持つテーブル同士の間には、中間テーブルを用意します。

理由は、ユーザーがルームに属する毎にカラムが増えてしまうことを防ぐためです。

不要なカラムが増えてしまうことはDB設計上良くないこととされています。

 

中間テーブル

中間テーブルは、2つのモデルの関係性を保管するテーブルです。例えば、ユーザー1とユーザー2がルーム1に属しているとすると、中間テーブルには、

・id = 1 user_id = 1 room_id = 1

・id = 2 user_id = 2 room_id = 1

この2つのレコードが保存されます。これにより、どのユーザーとどのユーザーがどのルームに属しているのかがわかります。

 

throughオプション

中間テーブルを使って多対多のアソシエーションを記述する場合は、throughオプションを用います。

例えば、ユーザーが複数のルームに属することを示す場合は、

user.rb

has_many :room_users

has_many :rooms, through: room_users

このように記述します。

 

ここまでの条件を全て考慮してデータベースに表すと、以下のようになります。

 

# テーブル設計

## users テーブル

| Column   | Type   | Options     |
| -------- | ------ | ----------- |
| name     | string | null: false |
| email    | string | null: false |
| password | string | null: false |

### Association

- has_many :room_users
- has_many :rooms, through: room_users
- has_many :messages

## rooms テーブル

| Column | Type   | Options     |
| ------ | ------ | ----------- |
| name   | string | null: false |

### Association

- has_many :room_users
- has_many :users, through: room_users
- has_many :messages

## room_users テーブル

| Column | Type       | Options                        |
| ------ | ---------- | ------------------------------ |
| user   | references | null: false, foreign_key: true |
| room   | references | null: false, foreign_key: true |

### Association

- belongs_to :room
- belongs_to :user

## messages テーブル

| Column  | Type       | Options                        |
| ------- | ---------- | ------------------------------ |
| content | string     |                                |
| user    | references | null: false, foreign_key: true |
| room    | references | null: false, foreign_key: true |

### Association

- belongs_to :room
- belongs_to :user

 

 

参考

https://qiita.com/morikuma709/items/9fde633db9171b36a068

https://programming-beginner-zeroichi.jp/articles/25