一張 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)圖:
關(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)系圖:
關(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)系圖:
關(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)圖
關(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
更多現(xiàn)代化 PHP 知識(shí),請(qǐng)前往 Laravel / PHP 知識(shí)社區(qū)