Laravel Eloquent 模型關(guān)聯(lián)速查表

file

一張 Laravel’s Eloquent ORM 5.5 的速查表

一對(duì)一關(guān)聯(lián)

展示細(xì)節(jié):

在這個(gè)展示中,我們有 2 個(gè)模型(Owner 和 Car)及兩張表(owners 和 cars)夫晌。

商業(yè)邏輯:

一個(gè)使用者可以擁有一臺(tái)車宦芦。
一臺(tái)車可以有一個(gè)擁有者勉失。

關(guān)聯(lián)圖:

file

關(guān)聯(lián)細(xì)節(jié):

Cars 表必須儲(chǔ)存 Owner ID盒刚。

Eloquent 模型:

class Owner
{
    public function car()
    {
       return $this->hasOne(Car::class);
    }
}
class Car
{
    public function owner()
    {
        return $this->belongsTo(Owner::class);
    }
}

資料庫遷移:

Schema::create('owners', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('cars', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->integer('owner_id')->unsigned()->index()->nullable();
    $table->foreign('owner_id')->references('id')->on('owners');
});

儲(chǔ)存紀(jì)錄:

// 在 Owner 及 Car 之間建立關(guān)聯(lián)
$owner->car()->save($car);
// 在 Car 及 Owner 之間建立關(guān)聯(lián)
$car->owner()->associate($owner)->save();

取得紀(jì)錄:

// 取得 Owner Car
$owner->car;
// 取得 Car Owner
$car->owner;

一對(duì)多關(guān)聯(lián)

示例細(xì)節(jié):

在此示例中,我們有兩個(gè)模型:Thief (小偷) 和 Car (車)旬蟋,和兩張表:
thieves 和 cars 耘纱。

業(yè)務(wù)規(guī)則:

小偷可以偷走多輛車敬肚。
車只能被一個(gè)小偷偷走。

關(guān)系圖:

file

關(guān)系細(xì)節(jié):

車輛表應(yīng)該存儲(chǔ)小偷的 ID 束析。

Eloquent 模型:

class Thief
{
    public function cars()
    {
       return $this->hasMany(Car::class);
    }
}
class Car
{
    public function thief()
    {
        return $this->belongsTo(Thief::class);
    }
}

數(shù)據(jù)遷移:

Schema::create('thieves', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('cars', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->integer('thief_id')->unsigned()->index()->nullable();
    $table->foreign('thief_id')->references('id')->on('thieves');
});

記錄存儲(chǔ):

// 創(chuàng)建介于小偷與車之間的關(guān)聯(lián)艳馒。
$thief->cars()->saveMany([
   $car1, 
   $car2,
]);
// 或者在單一模型調(diào)用 save() 方法。
$thief->cars()->save($car);
// 創(chuàng)建介于 Car 和 Thief 的關(guān)聯(lián)员寇。
$car->thief()->associate($thief)->save();

拉取記錄:

// 獲取小偷所偷的車
$thief->cars;
// 獲取偷盜某輛車的小偷
$car->thief;

多態(tài)一對(duì)多關(guān)系

演示細(xì)節(jié):

在這個(gè)演示中弄慰,我們有三個(gè)模型(Man, Woman 和 Car),和三張表(man, women 和 cars)蝶锋。

業(yè)務(wù)規(guī)則:

一個(gè)男人(買家)可以買很多汽車陆爽。
一個(gè)女人(買家)可以買很多汽車。
這個(gè)汽車可以被一個(gè)買家購買(男人或女人)扳缕。

關(guān)系圖:

file

關(guān)系詳情:

Car表應(yīng)該儲(chǔ)存買家 ID 和買家類型慌闭。
"buyer" 是一組模型名稱 (男人 和 女人), 它不僅限于兩者躯舔,buyer 類型是模型的真實(shí)名稱 驴剔。

Eloquent 模型:

class Man
{
    public function cars()
    {
        return $this->morphMany(Car::class, 'buyer');
    }
}
class Woman
{
    public function cars()
    {
        return $this->morphMany(Car::class, 'buyer');
    }
}
class Car
{
    public function buyer()
    {
        return $this->morphTo();
    }
}

數(shù)據(jù)庫遷移:

Schema::create('men', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('women', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('cars', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->integer('buyer_id')->unsigned()->index()->nullable();
    $table->string('buyer_type')->nullable();   
    // 或者使用 $table->morphs(‘buyer’); 代替 "buyer_id" 和 "buyer_type"
});

儲(chǔ)存記錄:

// 在買家 (男人 / 女人) 和汽車之間建立聯(lián)系。
$man->cars()->saveMany([
   $car1, 
   $car2,
]);
$woman->cars()->saveMany([
   $car1, 
   $car2,
]);
// 或者為單個(gè)模型使用 save() 函數(shù)粥庄。
$man->cars()->save($car);
$woman->cars()->save($car);
//創(chuàng)建汽車與買家之間的關(guān)系 ( 男人/女人 )丧失。
$car1->buyer()->associate($man)->save();
$car2->buyer()->associate($woman)->save();

檢索記錄:

// 獲取買家 (男人 / 女人)的汽車
$men->cars
$women->cars
// 獲取這輛車的買家 (男人 / 女人)
$car->buyer

多對(duì)多關(guān)聯(lián)

示例展示:

在這個(gè)示例中,我們有兩個(gè)模型(Driver 和 Car)惜互,和三張表
(drivers,名為 car_driver的中間關(guān)聯(lián)表).

業(yè)務(wù)規(guī)則:

一個(gè)司機(jī)可以駕駛很多輛車布讹。
一輛車可以被很多個(gè)司機(jī)開。

關(guān)系圖:

文件

關(guān)聯(lián)詳情:

關(guān)聯(lián)表"car_driver"應(yīng)該保存駕駛員ID和汽車ID训堆。

關(guān)聯(lián)模型:

class Driver
{
    public function cars()
    {
       return $this->belongsToMany(Car::class);
    }
}
class Car
{
    public function drivers()
    {
        return $this->belongsToMany(Driver::class);
    }
}

數(shù)據(jù)庫遷移:

Schema::create('drivers', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('cars', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('car_driver', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('car_id')->unsigned()->index();
    $table->foreign('car_id')->references('id')->on('cars')->onDelete('cascade');
    $table->integer('driver_id')->unsigned()->index();
    $table->foreign('driver_id')->references('id')->on('drivers')->onDelete('cascade');
});

保存記錄:

//創(chuàng)建Driver和Car之間的關(guān)聯(lián)炒事。
$driver->cars()->attach([
   $car1->id,
   $car2->id,
]);
//或者使用sync()函數(shù)防止重復(fù)關(guān)聯(lián)。
$driver->cars()->sync([
   $car1->id,
   $car2->id,
]);
//創(chuàng)建Car和Driver之間的關(guān)聯(lián)蔫慧。
$car->drivers()->attach([
   $driver1->id,
   $driver2->id,
]);
//或者使用sync()函數(shù)防止重復(fù)關(guān)聯(lián)。
$car->drivers()->sync([
   $driver1->id,
   $driver2->id,
]);

查詢記錄:

// Get Driver Car
$driver->cars
// Get Car Drivers
$car->drivers

多對(duì)多多態(tài)關(guān)聯(lián)

展示細(xì)節(jié):

在這個(gè)展示中我們有三個(gè)模型(Valet权薯、Owner 及 Car)和 4 張表(valets姑躲、owners睡扬、cars 及 drivers)。

商業(yè)邏輯:

一個(gè)代駕(司機(jī))可以駕駛很多輛車
一個(gè)車主(司機(jī))可以駕駛很多輛車
一臺(tái)車可以被很多個(gè)司機(jī)駕駛(代駕和 / 或車主)

關(guān)聯(lián)圖

file

關(guān)聯(lián)細(xì)節(jié):

中間表「drivers」應(yīng)該儲(chǔ)存駕駛?cè)?ID黍析、駕駛?cè)祟愋图败囕v ID卖怜。
駕駛是一個(gè)模型集合的代稱(Valet 及 Owner),而且不限定兩個(gè)模型阐枣。駕駛?cè)祟愋褪悄P偷恼嬲Q马靠。

Eloquent 模型:

class Valet
{
    public function cars()
    {
        return $this->morphToMany(Car::class, 'driver');
    }
}
class Owner
{
    public function cars()
    {
        return $this->morphToMany(Car::class, 'driver');
    }
}
class Car
{
    public function valets()
    {
        return $this->morphedByMany(Valet::class, 'driver');
    }

    public function owners()
    {
        return $this->morphedByMany(Owner::class, 'driver');
    }
}

資料庫遷移:

Schema::create('valets', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('owners', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});
Schema::create('drivers', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('driver_id')->unsigned()->index();
    $table->string('driver_type');
    // 或使用 $table->morphs(‘driver’) 來取代「driver_id」和「driver_type」
    $table->integer('car_id')->unsigned()->index();
    $table->foreign('car_id')->references('id')->on('cars')->onDelete('cascade');
});

儲(chǔ)存紀(jì)錄:

// 在 driver(Valet / Owner)和 Car 間建立關(guān)聯(lián)
$valet->cars()->saveMany([$car1, $car2]);
$owner->cars()->saveMany([$car1, $car2]);
// 或使用 save() 方法來儲(chǔ)存單一模型
$valet->cars()->save($car1);
$owner->cars()->save($car1);
// 在 Car 和 driver(Valet / Owner)間建立關(guān)聯(lián)
$car->valets()->attach([
    $valet1->id,
    $valet2->id,
]);
$car->owners()->attach([
    $owner1->id,
    $owner2->id,
]);
// 或是用 sync() 方法來避免重複關(guān)聯(lián)
$car->valets()->sync([
    $valet1->id,
    $valet2->id,
]);
$car->owners()->sync([
    $owner1->id,
    $owner2->id,
]);

取得紀(jì)錄:

// 取得 driver(Valet / Owner)的 Cars
$valet->cars
$owner->cars

// 取得 Car 的 drivers(Valet 及 Owner)
$car->owners
$car->valets

file

更多現(xiàn)代化 PHP 知識(shí),請(qǐng)前往 Laravel / PHP 知識(shí)社區(qū)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔼两,一起剝皮案震驚了整個(gè)濱河市甩鳄,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌额划,老刑警劉巖妙啃,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異俊戳,居然都是意外死亡揖赴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門抑胎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燥滑,“玉大人,你說我怎么就攤上這事阿逃∶。” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵盆昙,是天一觀的道長(zhǎng)羽历。 經(jīng)常有香客問我,道長(zhǎng)淡喜,這世上最難降的妖魔是什么秕磷? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮炼团,結(jié)果婚禮上澎嚣,老公的妹妹穿的比我還像新娘。我一直安慰自己瘟芝,他們只是感情好易桃,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锌俱,像睡著了一般晤郑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天造寝,我揣著相機(jī)與錄音磕洪,去河邊找鬼。 笑死诫龙,一個(gè)胖子當(dāng)著我的面吹牛析显,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播签赃,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼谷异,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了锦聊?” 一聲冷哼從身側(cè)響起歹嘹,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎括丁,沒想到半個(gè)月后荞下,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡史飞,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年尖昏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片构资。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡抽诉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吐绵,到底是詐尸還是另有隱情迹淌,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布己单,位于F島的核電站唉窃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纹笼。R本人自食惡果不足惜纹份,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望廷痘。 院中可真熱鬧蔓涧,春花似錦、人聲如沸笋额。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兄猩。三九已至茉盏,卻和暖如春鉴未,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鸠姨。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國打工歼狼, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人享怀。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像趟咆,于是被迫代替她去往敵國和親添瓷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容

  • http://big5.china.com/gate/big5/auto.china.com/life/more/...
    wokeman閱讀 2,522評(píng)論 0 1
  • 中文名稱(Chinese name): 月球漫步者 英文名稱(English name): MOONWALKER ...
    JENTSON閱讀 1,233評(píng)論 0 2
  • 說不定哪天值纱。 我自己就懶死了
    radio閱讀 206評(píng)論 0 1
  • 人生就像是一場(chǎng)旅行鳞贷,你看到的是陽光,那就是陽光虐唠,你看到的是陰霾搀愧,那就是陰霾。 人生就像是一次選擇疆偿,你想到是前方咱筛,那...
    前度小花靜院閱讀 184評(píng)論 1 1
  • 今天學(xué)習(xí)每股收益,反映的是每一份股票給股東帶來的收益杆故。 學(xué)習(xí)財(cái)報(bào)需要反復(fù)計(jì)算練習(xí)思考 不要短期希望過高迅箩,長(zhǎng)期希望過...
    浩苒閱讀 195評(píng)論 0 1