2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【laravel】Eloquenによるリレーション

Last updated at Posted at 2020-05-22

概要

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を表示しています。

Controller
public function index(Request $request)
{
  $items = Sample::all();
  return view('sample.index', ['items' => $items]);
}
Sample
public function list()
{
  return $this->hasOne('App\Models\List');
}
view
@foreach ($items as $item)
  @if ($item->list != null)
    {{$item->list->title}}
  @endif
@endforeach

hasManyメソッド

hasMany()は1対多の結合で、従テーブルの全てのレコードを取得します。
また、設定がなければ外部キーは〇〇_idとされますが、オプションで第2引数によって指定できます。

例はhasOne()で作成した内容とほぼ同じです。

Controller
public function index(Request $request)
{
  $items = Sample::all();
  return view('sample.index', ['items' => $items]);
}
Sample
public function lists()
{
  return $this->hasMany('App\Models\List');
}
view
@foreach ($items as $item)
  @if ($item->lists != null)
    {{$item->lists->title}}
  @endif
@endforeach

レコードの有無を判定して取得

hasOne()hasMany()は従テーブルのレコードがNULLでもNULLとして返すため、INNERJOINのような使い方ができません。
そこでhas()という値があるレコードのみを取得するメソッドです。
また、逆に値がNULLとしてのレコードを取得するdoesntHave()というメソッドもあります。
has()クラスモデル::has('メソッド名')->get();のように記述します。

Controller
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);
}
view
@foreach ($hasItems as $has)
  {{$has->lists->title}}
@endforeach

@foreach ($noItems as $no)
  {{$no->lists->title}}
@endforeach

belongsTo

belongsTo()は従テーブルから主テーブルのレコードを取得するメソッドです。
主テーブルのレコードが削除されていた場合はNULLで返されず例外が発生します。

また、従テーブルの〇〇_idに一致する主テーブルのidを検索して結合しますが、従テーブルで設定する外部キーはオプションで第2引数によって指定できます。

List
public function sample()
{
  return $this->belongsTo('App\Models\Sample');
}
view
@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)

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?