Laravelの1対1リレーションのbelongsToについて、公式マニュアルでは専用単語ばかりでどうしてもわかりにくいと感じてしまっている方へ向けて、わかりやすく解説しました。
※例で紹介しているコードについては、一部英語を日本語表記で使用している部分もありますので、コピペで使用する方は必要に応じて置き換えてください。
今回は以下のLaravel7系の公式マニュアルを参考にしながらまとめています。
親から子へのリレーション(hasOne)について詳しく知りたい方は、以下をご参考ください。
belongsTo(子から親へ)
# 公式より
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Phone extends Model
{
/**
* この電話を所有するUserを取得
*/
public function user()
{
return $this->belongsTo('App\User');
}
}
1対1のリレーションとは、とあるテーブルの1つの要素と別のテーブルの1つの要素の関係を結びつけることです。この時、どちらかが複数になることはありません。
そのため、イレギュラーがなければ各テーブルの行数は以下の関係が成り立ちます。
親 ≧ 子
親のいない子が生まれるということは有りえませんので当然のことです。
※道徳的な意味は除きます
ここで重要になるのは、テーブル関係のどちらが親で、どちらが子に該当するかです。これはテーブル内の値の持ち方によって決められます。
公式マニュアル通り、ユーザーと電話のテーブルで考えてみましょう。
上記テーブル関係の場合、ユーザーが親で電話が子になります。この見分け方は、判別するためのIDを持っているテーブルが子になるということです。電話テーブルにはユーザーを判別するための「ユーザー_id」がありますね。
判別するIDを持っている方が子になる
親と子の見分け方がわかったので、次にbelongsToについて見ていきましょう。
公式マニュアルのコードをわかりやすく上記テーブルのように日本語へ置き換えて考えます。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class 電話 extends Model
{
public function ユーザー()
{
return $this->belongsTo('App\ユーザー);
}
}
belongsToは子から親に結びつけるためのリレーションなので、電話のモデルに記述します。この時、ユーザーのモデルが存在しなければリレーションができないので、事前に準備しておきましょう。
引数の解説
belongsTo('モデル', '外部キー[省略可]', 'カスタムキー[省略可]');
belongsToでは上記のように第3引数まで設定でき、第2、3引数は省略することが可能です。それでは1つずつ順番に確認していきましょう。
第1引数
モデルには、リレーション先(親)のモデルを指定します。今回であれば、子である電話テーブルに「親のユーザーテーブルと結びつける」という指示を出したいので、第一引数には親に該当するユーザーモデルを指定します。
return $this->belongsTo('App\ユーザー');
Laravelのテーブル命名規則に従っていれば、これだけでリレーション関係を結びつけることができます。
リレーションで役立つLaravelのテーブル命名規則をざっくり解説
-
親テーブル側の判別カラムが「id」
※カスタムプライマリーキーでも可 -
子テーブル側の判別カラムが「親テーブル単数名 + _id」
今回は上記の条件が満たされているので、第2、第3引数は省略可能です。
第2引数
第2引数では、外部キー(foreign_key)を指定することができます。外部キーという表現がわかりにくい場合は「親を判別するための値が格納されている、子テーブルのカラム名」と考えてください。
belongsToの外部キーとは
親を判別するための値が格納されている、子テーブルのカラム名
今回のテーブル関係であれば親は「ユーザー」、子が「電話」ですね。電話が持つユーザーを判別する値は「ユーザー_id」なので、省略した場合は第2引数にはこの値が初期値としてセットされることになります。
return $this->belongsTo('App\ユーザー', 'ユーザー_id');
例えば、テーブルのカラムが以下の用に設定されていたケースで考えてみましょう。
これだと第1引数でモデルを指定しても、命名規則に従っていなければどのユーザーのidと電話のどの値が一致する行と結びつければいいかわかりません。上記テーブルであれば、親であるユーザーを判別している値が格納されている子テーブルのカラムは「ユーザー番号」なので、以下のようにリレーションを指定します。
return $this->belongsTo('App\ユーザー', 'ユーザー番号');
こうすることで、リレーション先のカラム名に関係なくリレーション関係を結ぶことができます。
第3引数
第3引数ではカスタムキー(other_key)を指定することができます。こちらもわかりやすく言い換えれば、「親を判別する値が格納された親テーブルが持つカラム」です。第3引数を省略した場合は、親の主キーが格納されます。
belongsToのカスタムキーとは
親を判別する値が格納された親テーブルが持つカラム
以下のテーブルで考えてみましょう。
※idの値を使用して判別するのが一般的で、このような格納方法をしているケースはまずありませんが、belongsToをわかりやすく理解するために上記テーブル関係を使用します
第2引数では子(電話)が持つ親(ユーザー)を判別する値が格納されたカラムを指定するので「ユーザーの名前」が入ります。そして、第3引数では親(ユーザー)を判別する値が格納された親が持つカラムを指定するので「名前」を指定します。
return $this->belongsTo('App\ユーザー', 'ユーザーの名前', '名前');
これでリレーションを結ぶことができました。第3引数までを上手く利用すれば、1対1の関係性が成立していればリレーションを結べます。
まとめ
いかがだったでしょうか。
今回はLaravelの1対1リレーション「hasOneについて」をわかりやすく解説しました。
公式マニュアルを見ても専用単語ばかりで分かりづらいと感じて曖昧なままリレーションを使っていたり、断念してしまった方はぜひ参考にしてくださいね。
親から子へのリレーション(hasOne)について詳しく知りたい方は、以下をご参考ください。
Laravelの基礎を学習したい方は、以下の書籍が参考になります。