データベースのリレーションシップ
データベースのリレーションシップとは、複数のテーブル間に存在する関連性を示すものです。例えば、ユーザーにプロフィールを1対1の関係で紐づけたり、ユーザーと投稿を1対多の関係で紐づけたり、ユーザーと学習講座を多対多の関係で紐づけたりします。関係性を図に表すと以下の通りになります。



1対1の関係
1対多の関係
多対多の関係
データベース同士の関係性は以上の3種類に分類されます。Laravelでは以上の3種類の関係性を表す方法が用意されています。
1対1の関係性の設定方法
データベース同士の関係性を規定するには、モデルへの記述が必要になります。ここでは、UserモデルとProfileモデルの1対1の関係性を設定します。まず、Profileモデルを作成します。Profileモデルは以下の要素を持っています。
カラム名 | 内容 |
user_id | 関連付けるUserのID 外部キー |
birthplace | 出身地 |
birthday | 誕生日 |
description | 自己紹介 |
外部キーとは、そのデータベースが指定した外部のデータベースを参照できるようにするためのキーです。ここでは、usersテーブルのidが外部キーとなります。上記の構造をデータベースに設定するためにはマイグレーションファイルを以下のように記述します。
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->foreignId("user_id")->constrained();
$table->string("birthplace");
$table->date("birthday");
$table->text("description");
$table->timestamps();
});
ここで、foreignIdメソッドは外部キーを指定するメソッドで、引数は「テーブル名(単数形)_id」となります。上記では、usersテーブルを指定していることになります。constrainedメソッドは自動的に参照のテーブルとカラムを指定します。
モデルに関係性を記述
次に、モデルに関係性を記述します。Userモデル、Profileモデルに以下のようにメソッドを追加します。
Userモデル
public function profile() {
return $this->hasOne(Profile::class);
}
Profileモデル
public function user() {
return $this->belongsTo(User::class);
}
hasOneメソッドは1対1のリレーションシップを定義するメソッドで、指定されたモデルのクラスを参照するようにします。belongsToメソッドはhasOneメソッドとは逆方向に参照するリレーションシップを定義します。
関係性のテスト
設定した関係性をテストします。テストには対話型のシェル、tinkerを使用します。tinkerはLaravelが提供する対話型のシェルで、対話型のシェルとは、コマンドを記述し、実行するとすぐに実行結果が返ってくるシステムのことです。以下のコマンドで、tinkerを起動できます。
php artisan tinker
次に、以下のコマンドでダミーのユーザーデータとプロフィールデータを作成します。
use App\Models\User;
use App\Models\Profile
#ダミーユーザー
$user = new User();
$user->name = "test";
$user->email = "test@example.com";
$user->password = Hash::make("password");
$user->is_admin = false;
$user->save();
#ダミープロフィール
$profile = new Profile();
$profile->user_id = 1;
$profile->birthday = "2000/01/01";
$profile->birthplace = "Tokyo";
$profile->description = "test";
ここで、user_idにはダミーユーザーのidを設定します。
次に、データベースの関係性が設定できているかどうか確認します。以下のコマンドでユーザーからプロフィール、プロフィールからユーザーにアクセスできるか確認してください。
$user->profile;
$profile->user;
上記のコマンドで、プロフィール、ユーザーの情報が取得できれば成功です。
今回はリレーションシップの1対1について解説しました。次回以降では、1対多、多対多について解説していきます。