記事の内容
概要
リレーションは、複数のテーブル間の関係性を簡単に定義し、データを効率的に取得するための機能です。
メソッド名 | 説明 |
---|---|
hasOne | 1対1リレーションを定義 |
hasMany | 1対多リレーションを定義 |
belongsTo | 親モデルへのリレーションを定義 |
belongsToMany | 多対多リレーションを定義 |
1対1
関係性
Customer ─ Membership
├─Rental ─ Item
│ └─── Item
│ ┌────┘
└─Rental ─ Item
└─── Item
【ファイル先】app/Models/Customer.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
public function membership()
{
return $this->hasOne(Membership::class);
}
}
【ファイル先】app/Models/Membership.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Membership extends Model
{
use HasFactory;
public function customer()
{
return $this->belongsTo(Customer::class);
}
}
1対多
関係性
Customer ─ Membership
├─Rental ─ Item
│ └─── Item
│ ┌────┘
└─Rental ─ Item
└─── Item
【ファイル先】app/Models/Customer.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
public function rentals()
{
return $this->hasMany(Rental::class);
}
}
【ファイル先】app/Models/Rental.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Rental extends Model
{
use HasFactory;
public function customer()
{
return $this->belongsTo(Customer::class);
}
}
多対多
関係性
Customer ─ Membership
├─Rental ─ Item
│ └─── Item
│ ┌────┘
└─Rental ─ Item
└─── Item
【ファイル先】app/Models/Rental.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Rental extends Model
{
use HasFactory;
public function items()
{
return $this->belongsToMany(Item::class);
}
}
【ファイル先】app/Models/Item.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Item extends Model
{
use HasFactory;
public function rentals()
{
return $this->belongsToMany(Rental::class);
}
}
その他
条件付きリレーション
リレーションに対して条件を追加することで、特定のデータだけを取得することができます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
// 通常のリレーション
public function rentals()
{
return $this->hasMany(Rental::class);
}
// 条件付きリレーション
public function activeRentals()
{
return $this->hasMany(Rental::class)->where('status', 'active');
}
}
リレーションのデフォルトモデル
リレーションが存在しない場合に、デフォルトのモデルを返す方法があります。withDefault
メソッドを使うことで実現可能
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
/**
* Customerは1つのMembershipを持つ(1対1のリレーション)
* リレーションが存在しない場合、デフォルトの値を返す
*/
public function membership()
{
// hasOneリレーションを定義し、デフォルトで 'type' => 'standard' を設定
return $this->hasOne(Membership::class)->withDefault([
'type' => 'standard',
]);
}
}
カスタム中間テーブルのデータ
多対多のリレーションでは、中間テーブルに追加のフィールドがある場合、
そのフィールドを取得・操作することができます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Rental extends Model
{
use HasFactory;
/**
* Rentalは多くのItemと多対多のリレーションを持つ
* 中間テーブルには 'rental_date' フィールドも含まれる
*/
public function items()
{
// belongsToManyリレーションを定義し、中間テーブルの 'rental_date' を使用可能にする
return $this->belongsToMany(Item::class)->withPivot('rental_date');
}
}
リレーションのサブクエリ
リレーション内でサブクエリを使って、集計や特定の条件に合致するデータを効率的に取得できます。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model
{
use HasFactory;
/**
* Customerの最新のRentalを取得
* latest()を使って、最も新しいRentalを1つ取得する
*/
public function latestRental()
{
// hasOneリレーションを定義し、最新のRentalを取得
return $this->hasOne(Rental::class)->latest();
}
}