39
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

中間テーブルを用いた処理(Rails)

Posted at

中間テーブルとは

中間テーブルは多対多の関係を表現するためのテーブルのことです。
テーブル同士が複数のレコードと対応している際に、中間テーブルを用いなければ非常に冗長なテーブル設計となってしまいます。
これだけでは意味不明だと思うので、下記の実例もよければ参考にしてください。

テーブル設計

今回はgroupsテーブルとusersテーブルを作成します。
グループには複数のユーザーが所属し、ユーザーは複数のグループに所属できる、という仕様にするためgroupsテーブルとusersテーブルは多対多の関係になります。
この関係を整理するために、ユーザーが所属するグループと、グループに所属しているユーザーを管理する中間テーブル(group_usersテーブル)を作成します。
スクリーンショット 2021-04-19 1.45.20.png

中間テーブルを作らなかったら?

usersテーブルでユーザーが所属するグループを管理、もしくはgroupsテーブルでグループに所属しているユーザーを管理する事になります。
下記の例では、usersテーブルでユーザーが所属するグループを管理しています。
これではユーザーが新しいグループに参加するたびに、usersテーブルのカラムを増やす事になるため、テーブル設計時にカラム数を決めることができません。
スクリーンショット 2021-04-19 1.45.32.png

カラムを増やさないために以下のようなテーブル設計にすることもできますが、これではusersテーブルに同じユーザーが2人以上存在する事になってしまいます。
スクリーンショット 2021-04-19 1.51.53.png

実装編

今回はRailsを用いて、グループにユーザーを追加する処理を実装してみます。

モデルの実装内容は以下の通り。
・Userモデル

class User < ApplicationRecord
  has_many :group_users
  has_many :groups, through: :group_users
end

・Groupモデル

class Group < ApplicationRecord
  has_many :group_users
  has_many :users, through: :group_users
end

・GroupUserモデル

class GroupUser < ApplicationRecord
  belongs_to :user
  belongs_to :group
end

画面の動きとしては、以下のGif画像のように登録ボタンを押下したらgroupに登録される感じです。
bf5d192c77ea650caec24faff33379c3.gif

コントローラー側ではadd_userというユーザー追加用のメソッドを定義しています。
このメソッドの4行目でリレーションを追加する事により、中間テーブルにグループとユーザーが追加されます。

  def add_user
    @group = Group.find(params[:group_id])
    user = User.find(params[:user_id])
    @group.users << user
    redirect_to group_path, notice: "ユーザーを追加しました。"
  end
39
34
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
39
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?