【Laravel】リレーションとは:モデルのリレーションについて
2023.10.06 /
本記事ではLaravelにおける、モデルのリレーションについて詳しく解説していきます。
リレーションとは複数のテーブルを関連付けることを意味します。テーブル同士をリレーションすることで、リレーション先のテーブルからデータを簡単に取得することができます。
アプリケーション開発では複数のテーブルが関連しあって動作します。リレーションはLaravelでのアプリケーション開発で必須の知識です。本記事を通して、モデルのリレーションについて理解を深めてください。
ここではLaravel10を使用しています。
テーブルのリレーションとは
アプリケーションを開発する際に、単一のテーブルのみで動くアプリケーションは稀です。基本的には複数のテーブルが関連しあい、複数のテーブルを組み合わせて1つのアプリケーションを開発します。
テーブル同士を関連付けすることで、効率的に希望のレコードを取得でき、不必要なデータベースのアクセスを削減できます。このように複数のテーブルを関連付けることをリレーションと呼びます。
例えばツイートアプリケーションではusersテーブルとtweetsテーブルを用意します。ツイートは1人のユーザーが何度でもツイートできるものとします。アプリケーションでは特定のユーザーが行ったツイートのみを表示するような仕組みが必要になります。このような場合、テーブル同士がリレーションしていることで、UserのIDからそのユーザーが行ったツイートのレコードをTweetsテーブルから簡単に取得することができます。
リレーションを利用してテーブル同士が関連しあうことで、アプリケーションの仕組みを簡単に実装できるようになります
Laravelでリレーションを設定する方法
Laravelには「Eloquent(エロクアント)」というORMが備わっており、モデル同士を紐づけることによって自動で関連するデータの取得をサポートします。
Eloquentではテーブル同士の関連付け(リレーション)を簡単にかつシンプルに扱えます。無駄なデータベースアクセスを減らすだけでなく、可読性の高いコードを書くことができます。
Laravelではテーブル同士のリレーションはモデルに記述します。
モデルとはMVCモデルのM(Model)にあたり、データベースとアプリケーションの架け橋となる機能です。アプリケーションでデータベース操作(取得・追加・変更・削除)を行うためにモデルは利用されます
【Laravel】モデルとは:Modelの概要や作成方法について
つまりモデルにリレーションを記述してテーブル同士を関連付けることで、関連したテーブルのレコードを簡単に取得することができるということです。
2つのテーブルの関係
テーブル同士を関連付けるには「テーブルの関係」を考える必要があります。モデルでテーブルのリレーションを書く際に、テーブルの関係によって使用するメソッドが異なります。
テーブルの関係は以下の通りです。
テーブルの関係 | 説明 |
---|---|
has One | 2つのテーブルが1対1の関係。親テーブル側に関連付けを設定する。親テーブルから子テーブルのデータを取得するための設定 |
has Many | 2つのテーブルが1対多の関係。親テーブル側に関連付けを設定する。親テーブルから子テーブルのデータを取得するための設定 |
belongs To | 子テーブル側に関連付けを設定する。子テーブルから親テーブルのデータを取得するための設定 |
親テーブルと子テーブルとは
関係のある2つのテーブルでは外部キーと呼ばれる関連するテーブルのIDを保管するフィールドがあります。例えばArticleテーブルとCategoryテーブルを考えると、ArticleテーブルにはCategoryテーブルと関連するためのcategory_idというフィールドを用意します。
このような場合、これらのテーブルはhas Manyの関係であり、参照先(紐づけされる側)であるCategoryテーブルが親テーブル、外部キーを定義するArticleテーブルが子テーブルとなります
【Laravel】migration:外部キー制約とは
2つのテーブルを関連付けるにはモデル内に以下構文に沿ってコードを記述します。
public function メソッド名()
{
return $this->テーブルの関係(リレーションモデル名::class);
}
モデルの関連付けに関しては次項の設定例を参考にしてください。
モデルでリレーションの設定例
ここではatrticlesテーブルとcategoriesテーブルを使ってどのように関連付け(リレーション)を行うのか簡単に解説します。
articlesテーブルとcategoriesテーブルはそれぞれ次のようにマイグレーションファイルを作成しています。
// articlesテーブルのマイグレーションファイル
public function up(): void
{
Schema::create('articles', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->longText('body');
$table->integer('flag');
$table->foreignId('category_id')->constrained();
$table->timestamps();
});
}
// categoriesテーブルのマイグレーションファイル
public function up(): void
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
次にこれらテーブル同士を関連付けます。以下ではCategoryモデルからArticleモデルに関連付けを行っています。
// app/Models/Category.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
use HasFactory;
public function article()
{
return $this->hasMany(Article::class);
}
}
Categoryテーブルは親テーブルなので、hasManyメソッドを使っています。これにより親テーブルのレコードから、関連する子テーブルのすべてのレコードを取り出すことができます。
またフィールドflagが1のレコードだけを取得したい場合は、where句を以下のように追加します。
public function article()
{
return $this->hasMany(Article::class)->where('flag', '=', 1);
}
次に以下ではArticleモデルからCategoryモデルに関連付けを行っています。
// app/Models/Article.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Tweet extends Model
{
use HasFactory;
public function category()
{
return $this->belongsTo(Category::class);
}
}
Articleテーブルは子テーブルなので、belongsToメソッドを使って子テーブルから親テーブルのレコードを取り出すことができるようにしています。
このようにモデルに関連付けを付け加えることで、モデル同士で関連するモデルのデータを取得できるようになります。