No_ideaのわからん日和

✏️...プログラミングが全然出来ない奴がわからんわからん言いながら様々な構文(記述方法やエラー構文など)と奮闘しながら成長していく成長記録です🐢

Ruby on Rails: 中間テーブルを使用したチャットグループの設定...chapter13-2

今日はチャットグループの設定を行います。

 

---------------- 今回行った事 ----------------

①DB設計

②モデル、テーブル作成

③モデルの設定

----------------------------------------------

 

 

①DB設計

チャットグループを作成します。

チャットグループ一つ一つにはユーザーを沢山持ち、ユーザーは沢山のチャットグループを持つことができます。

イメージ図:

これを多対多の関係と言います。

DB設計図:

しかし、これでは問題があります。

それはDBにあるテーブルに問題が生じてしまいます。

仮にchat_groupsテーブルにuser_idするためのカラムを用意してみるとすると、下の表のようになります。

だが、これは出来ません。

それはカラム一つには一つの値しか入れることが出来ないからです。

つまり、user_idに沢山のユーザーidを入れることはできないということ。

 

そこでこの問題を解決するのが中間テーブルです。

イメージ図:

DB設計図:

これでカラムには値が1つだけ入ることになるので、問題が解決されます。

 

それではREADMEにDBを設計していきます。

## usersテーブル
|Column|Type|Options|
|------|----|-------|
|nickname|string|null: false|
|email|string|null: false|
|password|string|null: false|
 


### Association
- has_many :chat_group_to_users
- has_many :chat_groups, through: :chat_group_to_users


 
  ・
  ・ (省略)
  ・


<!-- ユーザーとチャットグループの中間テーブル -->
## chat_group_to_usersテーブル
|Column|Type|Options|
|------|----|-------|
|user_id|integer|null: false, foreign_key: ture|
|chat_group_id|integer|null: false, foreign_key: ture|

### Association
- belongs_to :user
- belongs_to :chat_group




## chat_groupsテーブル
|Column|Type|Options|
|------|----|-------|
|chat_group_name|string|null: false|
|chat_group_description|text||

### Association
- has_many :chat_group_to_users
- has_many :users, through: :chat_group_to_users


 

今回はチャットグループではチャットグループ名とそのチャットグループに関する説明を付けたいと思うのでカラムはchat_group_nameとchat_group_descriptionを作成。

chat_group_nameは文字列であり、長く無いので型はString型。

さらにチャットグループ名は必ず入力しなければならないようにしたいので、null: false。

chat_group_descriptionはその作成したチャットグループの説明を入力したいので型はText型。

この説明は別に入力しなくても良いことにしたいのでオプションは付けないことにします。

 

次に中間テーブル。

中間テーブル名はchat_group_to_usersテーブル。

ここで管理するのはuser_idとchat_group_id。

この二つは整数で管理するので型はInteger。

さらにこの整数は必ずなくてはならないので空(何も無い状態)では保存できないようにnull: falseを設定。そして、この2つは外部キーとなります。

外部キーとは、他のテーブルの情報(今回はusersテーブルのid=user_idと、chat_groupsテーブルのid=chat_group_id)を使用すると言うこと。

これをforeign_keyで設定する。よって、foreign_key: trueとしてuser_idカラムとchat_groupカラムに設定。

 

次にusersテーブルとchat_groupsテーブルのアソシエーション について。

イメージ図:

まずはusersテーブルのアソシエーション について。

イメージ図をみるとusersテーブルと中間テーブルでは1対多の関係になっているので、has_many :chat_group_to_usersを設定。

さらにchat_groupsテーブルとの関係性だが、先ほども述べたように多対

多の関係性であるので、has_many :chat_groupsを設定します。しかし、このchat_groupsテーブルは一旦chat_group_to_usersテーブル(中間テーブル)を経由しての関係性なので、through :chat_group_to_usersを設定してあげます(throughの英単語の意味は『...を通って』)。

 

次にchat_groupsテーブルのアソシエーション について。

usersテーブルと同じように、chat_groupsテーブルとchat_group_to_usersテーブル(中間テーブル)との関係性は1対多。

なので、has_many :chat_group_to_usersと設定。

そして、usersテーブルとの関係性は多対多なのでhas_many :usersを設定します。そして、このhas_many :usersはchat_group_to_usersテーブルを経由しての関係なので、through :chat_group_to_usersを設定します。

 

そして最後に中間テーブルのアソシエーションについて。

中間テーブルとusersテーブルの関係性は多対1なので、belongs_to :user。

中間テーブルとchat_groupsテーブルの関係性は多対1なので、belongs_to :chat_groupと設定。

これでテーブルの設定、アソシエーションの設計が終わったので、chat_groupsテーブルとchat_group_usersテーブルの作成、モデルの作成をします。

参照:https://qiita.com/ramuneru/items/db43589551dd0c00fef9

 

 

 

 

②モデル、テーブル作成

1. chat_groupのモデルとテーブル作成

$rails g model ChatGroup chat_group_name:string chat_group_description:text

db/migrate/20200623071132_create_chat_groups.rb

class CreateChatGroups < ActiveRecord::Migration[6.0]
(修正前)
 def change
  create_table :chat_groups do |t|
   t.string :chat_group_name
   t.text :chat_group_description

   t.timestamps
  end
 
     ↓
(修正後)
 def change
  create_table :chat_groups do |t| 
   t.string :chat_group_name, null: false
   t.text :chat_group_description

   t.timestamps
  end
 
 end
end

$rails db:migrate

 

 

2.中間テーブル、モデルの作成

$rails g model ChatGroupToUser

db/migrate/20200623072426_create_chat_group_to_users.rb

class CreateChatGroupToUsers < ActiveRecord::Migration[6.0]
(修正前)
 def change
  create_table :chat_group_to_users do |t|
 
   t.timestamps
  end
 
     ↓
 
(修正後)
 def change
  create_table :chat_group_to_users do |t|
   t.references :chat_group, foregin_key: true
   t.references :user, foregin_key: true

   t.timestamps
  end
 
 end
end

references

英単語での意味『参照』。

references型を使用する目的としては、

  1. user_idやchat_group_idなど〇〇_idと言うカラムを自動で作成してくれる
  2. インデックスを自動に張ってくれる

・user_idやchat_group_idなど〇〇_idと言うカラムを自動で作成してくれる

〇〇_idと言うカラムを自動で作成してくれるので、:userとするとuser_idも作成してくれる。:chat_group→chat_group_idを自動作成してくれる。

 

・インデックスを自動に張ってくれる

インデックスとは特定のカラムからデータを取得する際に、テーブルの中の特定のカラムのデータを複製し検索しやすくしてくれるもの。インデックスを使用することでデーターの読み込みや取得を高速にしてくれる。デメリットとして書き込みが遅いと言う特徴がある。

参照:https://qiita.com/seiya1121/items/fb074d727c6f40a55f22

 

 

話を戻しますが、t.references :〇〇だけでは外部キーはつけることはできません。

reference型を設定し、外部キー(foregin_key: true)を設定することで外部キーを使用できるようになります。

参照:https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47

 

設定が終わったので、マイグレーションファイルを実行して DBに中間テーブルを作成します。

$rails db:migrate

これでモデルとテーブルは作成できました。

次にモデルを設定していきます。

 

 

 

 

 

③モデルの設定

userモデル

class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
 devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :validatable
 has_many :tweets
 has_many :chat_group_to_users
 has_many :chat_groups, through: :chat_group_to_users
end

 

chat_groupモデル

class ChatGroup < ApplicationRecord
 has_many :chat_group_to_users
 has_many :chat_group, through: :chat_group_to_users
end

 

chat_group_userテーブル(中間テーブル)

class ChatGroupToUser < ApplicationRecord
 belongs_to :user
 belongs_to :chat_group
end

 

これで各テーブルの関係性を示せました。

次回はチャットグループのページを作成していきます。

 

 

 

 

 

 

 

以上です。