1対1
1対多
多対多
Has Many Through
1対1(ポリモーフィック)
1対多(ポリモーフィック)
多対多(ポリモーフィック)
これらのうち 1対1 リレーションを操作してみます。
呼び出す側に記述します。
/**
* ● 1対1リレーション
* 対象モデル「App\Doctor」
*
*/
public function doctor()
{
return $this->hasOne('App\Doctor','id','doctor_id')->withDefault();
}
/**
* 1対1リレーション(hasOne) : ->created_user で作成したユーザーの情報を取得できるようにする
*
* @return \Illuminate\Database\Eloquent\Relations\hasOne
*/
public function created_user()
{
return $this->hasOne('App\User', 'id', 'created_user_id')->withDefault();
}
呼び出される側に記述します。
/**
* ● 1対1リレーション(belongsTo) : ->mt_branch で営業支店の情報を取得できるようにする
* 対象モデル「App\MtBranch」
*
*/
public function mt_branch()
{
return $this->belongsTo('App\MtBranch','branch_id')->withDefault();
}
外部キー(foreign key)を持つ側が belongsTo、外部キーを持たれる側が hasOne を使います。
データの発生順序で決めるののが非常に良いルール付けです。他にもいくつかの判断基準があります。
先に存在するデータ側が親(hasOne側)、後から作られるデータ側が子(belongsTo側、外部キーを持つ)
// ユーザー登録 → プロフィール作成
// users テーブル(先に存在)
// profiles テーブル(user_id を持つ)← 外部キー
User::create(...);
$user->profile()->create(...); // ユーザーがいないとプロフィールは作れない
独立して存在できる方が親、親がないと意味をなさない方が子
// Order(注文)は独立して存在できる
// Invoice(請求書)は注文がないと意味がない
// → invoices.order_id(外部キー)
// User(ユーザー)は独立して存在できる
// UserSettings(ユーザー設定)はユーザーがいないと意味がない
// → user_settings.user_id(外部キー)
親が削除されたら子も削除すべきもの → 子側に外部キー
// ユーザーを削除 → プロフィールも削除されるべき
// profiles.user_id に外部キー制約 ON DELETE CASCADE
// Product(商品)がメイン
// ProductDetail(商品詳細)が補助
// → product_details.product_id(外部キー)
// ❌ 迷うケース
// User と Profile、どちらに外部キーを?
// ✅ 判断:
// - ユーザー登録が先、プロフィール作成が後
// - ユーザーは独立して存在できる
// - プロフィールはユーザーなしでは意味がない
// → profiles.user_id に外部キー
データの発生順序で判断するのは、最も直感的で実装時の流れとも一致するため、良いルール付けです。