概要
Eloquentを使用したテーブルの結合です。
ここでは【laravel】マイグレーションで作成したsampleテーブルを主テーブルとして、「id、sample_id、title」で構成された従テーブルのlistテーブルが存在すると仮定します。
全てをまとめて一つの記事として投稿したかったのですが長くなったため分割しました。
Eloquentの基本的な部分と操作については以下の記事をご参考ください。
【laravel】Eloquentの基本
データベースの操作:Eloquent ORM編
まずは結合
Eloquentでの結合にはhasOne()
とhasMany()
というメソッドがあります。
hasOne()
は1対1の結合で、hasMany()
は1対多の結合です。
どちらもLEFTJOINのように主テーブルから従テーブルのレコードを取得し、値が存在しないレコードはNULLとしています。
これらの結合は主テーブル側で設定を記述します。
ただし、NULLのレコードをテンプレートで表示すると例外が発生するので対策が必要です。
hasOneメソッド
hasOne()
は1対1での結合で、従テーブルの最初のレコードのみを取得します。
また、設定がなければ外部キーは〇〇_id
とされますが、オプションで第2引数によって指定できます。
例として以下のような内容を作成します。
コントローラーで全ての値を取得してテンプレートへ渡し、モデルクラスではlistメソッドを作成してhasOne()
を返します。
テンプレートではforeachで値を取得して、値がNULLでなければクラスモデルで作成したlistメソッドのうちのtitleを表示しています。
public function index(Request $request)
{
$items = Sample::all();
return view('sample.index', ['items' => $items]);
}
public function list()
{
return $this->hasOne('App\Models\List');
}
@foreach ($items as $item)
@if ($item->list != null)
{{$item->list->title}}
@endif
@endforeach
hasManyメソッド
hasMany()
は1対多の結合で、従テーブルの全てのレコードを取得します。
また、設定がなければ外部キーは〇〇_id
とされますが、オプションで第2引数によって指定できます。
例はhasOne()
で作成した内容とほぼ同じです。
public function index(Request $request)
{
$items = Sample::all();
return view('sample.index', ['items' => $items]);
}
public function lists()
{
return $this->hasMany('App\Models\List');
}
@foreach ($items as $item)
@if ($item->lists != null)
{{$item->lists->title}}
@endif
@endforeach
レコードの有無を判定して取得
hasOne()
やhasMany()
は従テーブルのレコードがNULLでもNULLとして返すため、INNERJOINのような使い方ができません。
そこでhas()
という値があるレコードのみを取得するメソッドです。
また、逆に値がNULLとしてのレコードを取得するdoesntHave()
というメソッドもあります。
has()
はクラスモデル::has('メソッド名')->get();
のように記述します。
public function index(Request $request)
{
$hasItems = Sample::has('lists')->get();
$noItems = Sample::doesntHave('lists')->get();
$param = ['hasItems' => $hasItems, 'noItems' => $noItems];
return view('Sample.index', $param);
}
@foreach ($hasItems as $has)
{{$has->lists->title}}
@endforeach
@foreach ($noItems as $no)
{{$no->lists->title}}
@endforeach
belongsTo
belongsTo()
は従テーブルから主テーブルのレコードを取得するメソッドです。
主テーブルのレコードが削除されていた場合はNULLで返されず例外が発生します。
また、従テーブルの〇〇_id
に一致する主テーブルのid
を検索して結合しますが、従テーブルで設定する外部キーはオプションで第2引数によって指定できます。
public function sample()
{
return $this->belongsTo('App\Models\Sample');
}
@foreach ($items as $item)
@if ($item->sample != null)
{{$item->sample->name}}
@endif
@endforeach
参考
[Laravel 6.x Eloquent:リレーション]
(https://readouble.com/laravel/6.x/ja/eloquent-relationships.html)