laravel モデルのリレーション「多対多」を理解(前半;テーブル作成まで)

eloquentとマイグレーションを使ってTaskHEROのモデルとテーブルを作成していきます。

その前に、「多対多」の結合のlaravel内での書き方を知らなかったので勉強してきました。

参考までにリレーションの種類は次の4種類あります。

  • 1対1、hasOne – belongsTo
  • 1対多、hasMany – belongsTo
  • 多対1、belongsTo – hasMany
  • 多対多、belongsToMany – belongsToMany

このなかでも「多対多」の関係がちょっとめんどうなので整理しておきます。ほかの関係は初級者向け参考書とかでも乗っていますが、「多対多」は解説がなかったので盲点でした。

この記事では、「多対多」について前半でまとめながら、実際に作成する「users」「roles」テーブルを例にマイグレーションの実行からモデルの作成までをまとめていきます。

(長くなったのでモデルの作成は次回の記事へ続きます。最後にリンクはります)

usersテーブルとrolesテーブルの関係

アクセス権限ごとにユーザーのアクセス範囲を設定するにはユーザーにrole(役割、権限)を与えるのがベストです。

1人のユーザーが1つのroleを持つとしたらこんな関係になります。

1人のユーザーが1つの権限をもつばあい

これは「1対多」のhasMany結合です。

ただし、1人のユーザーが複数の権限を持てるようにするには「多対多」の関係となり、間にリレーション用のテーブルを用意する必要があります。

1人のユーザーが複数の権限を持つ

これをlaravelで実装する手順をまとめます。

テーブル名の規約

  • users
  • roles
  • role_user

ユーザー、権限テーブルはそれぞれ複数形、中間テーブルはそれぞれのテーブル名の単数形を五十音順で並べてスネークケースで定義します。

作成するモデル

  • UserModel
  • RoleModel

この2つだけで問題ないです。中間テーブルモデルは不要です。ただし、中間テーブルにもなにか属性があるような場合、カスタム中間モデルを作成して利用することもあります。

こんかいはとくにそういったカラムがないのでモデルなしで進めます。

artisanコマンドで作成

Userモデルは最初から用意されているのでRoleモデルを作成していきます。

php artisan make:model モデル名 -a

でRoleモデルを作成していきます。オプション-aでいろいろついてきます。

php artisan make:model Role -a
 Model created successfully.
 Factory created successfully.
 Created Migration: 2021_01_10_175917_create_roles_table
 Controller created successfully.

中間テーブルもマイグレーションファイルを作成します。

php artisan make:migration create_role_user_table

usersテーブル

こんな感じです。テーブル構造はめんどうなのでマイグレーションファイルですみません。

Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name')->unique();
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
            $table->string('disp_name');
            $table->text('profile');
            $table->string('icon_link');
        });

rolesテーブル

Schema::create('roles', function (Blueprint $table) {
            $table->tinyIncrements('id');
            $table->char('name', 100);
            $table->tinyInteger('level');
            $table->timestamps();
        });

role_userテーブル

Schema::create('role_user', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('user_id');
            $table->integer('role_id');
            $table->timestamps();
        });

マイグレーションを実行します。

php artisan migrate

php artisan migrate
 Migrating: 2014_10_12_000000_create_users_table
 Migrated:  2014_10_12_000000_create_users_table (0.12 seconds)
 Migrating: 2021_01_10_175917_create_roles_table
 Migrated:  2021_01_10_175917_create_roles_table (0.04 seconds)
 Migrating: 2021_01_10_180504_create_role_user_table
 Migrated:  2021_01_10_180504_create_role_user_table (0.04 seconds)

テーブルの作成まで完了しました!

次回はモデルを作成していきます。