Laravel Eloquent 模型关联速查表

作者: summerbluet | 来源:发表于2018-08-17 08:26 被阅读52次
    file

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

    一對一關聯

    展示細節:

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

    商業邏輯:

    一個使用者可以擁有一台車。
    一台車可以有一個擁有者。

    關聯圖:

    file

    關聯細節:

    Cars 表必須儲存 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');
    });
    

    儲存紀錄:

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

    取得紀錄:

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

    一对多关联

    示例细节:

    在此示例中,我们有两个模型:Thief (小偷) 和 Car (车),和两张表:
    thieves 和 cars 。

    业务规则:

    小偷可以偷走多辆车。
    车只能被一个小偷偷走。

    关系图:

    file

    关系细节:

    车辆表应该存储小偷的 ID 。

    Eloquent 模型:

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

    数据迁移:

    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');
    });
    

    记录存储:

    // 创建介于小偷与车之间的关联。
    $thief->cars()->saveMany([
       $car1, 
       $car2,
    ]);
    // 或者在单一模型调用 save() 方法。
    $thief->cars()->save($car);
    // 创建介于 Car 和 Thief 的关联。
    $car->thief()->associate($thief)->save();
    

    拉取记录:

    // 获取小偷所偷的车
    $thief->cars;
    // 获取偷盗某辆车的小偷
    $car->thief;
    

    多态一对多关系

    演示细节:

    在这个演示中,我们有三个模型(Man, Woman 和 Car),和三张表(man, women 和 cars)。

    业务规则:

    一个男人(买家)可以买很多汽车。
    一个女人(买家)可以买很多汽车。
    这个汽车可以被一个买家购买(男人或女人)。

    关系图:

    file

    关系详情:

    Car表应该储存买家 ID 和买家类型。
    "buyer" 是一组模型名称 (男人 和 女人), 它不仅限于两者,buyer 类型是模型的真实名称 。

    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();
        }
    }
    

    数据库迁移:

    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"
    });
    

    储存记录:

    // 在买家 (男人 / 女人) 和汽车之间建立联系。
    $man->cars()->saveMany([
       $car1, 
       $car2,
    ]);
    $woman->cars()->saveMany([
       $car1, 
       $car2,
    ]);
    // 或者为单个模型使用 save() 函数。
    $man->cars()->save($car);
    $woman->cars()->save($car);
    //创建汽车与买家之间的关系 ( 男人/女人 )。
    $car1->buyer()->associate($man)->save();
    $car2->buyer()->associate($woman)->save();
    

    检索记录:

    // 获取买家 (男人 / 女人)的汽车
    $men->cars
    $women->cars
    // 获取这辆车的买家 (男人 / 女人)
    $car->buyer
    

    多对多关联

    示例展示:

    在这个示例中,我们有两个模型(Driver 和 Car),和三张表
    (drivers,名为 car_driver的中间关联表).

    业务规则:

    一个司机可以驾驶很多辆车。
    一辆车可以被很多个司机开。

    关系图:

    文件

    关联详情:

    关联表"car_driver"应该保存驾驶员ID和汽车ID。

    关联模型:

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

    数据库迁移:

    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');
    });
    

    保存记录:

    //创建Driver和Car之间的关联。
    $driver->cars()->attach([
       $car1->id,
       $car2->id,
    ]);
    //或者使用sync()函数防止重复关联。
    $driver->cars()->sync([
       $car1->id,
       $car2->id,
    ]);
    //创建Car和Driver之间的关联。
    $car->drivers()->attach([
       $driver1->id,
       $driver2->id,
    ]);
    //或者使用sync()函数防止重复关联。
    $car->drivers()->sync([
       $driver1->id,
       $driver2->id,
    ]);
    

    查询记录:

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

    多對多多態關聯

    展示細節:

    在這個展示中我們有三個模型(Valet、Owner 及 Car)和 4 張表(valets、owners、cars 及 drivers)。

    商業邏輯:

    一個代駕(司機)可以駕駛很多輛車
    一個車主(司機)可以駕駛很多輛車
    一台車可以被很多個司機駕駛(代駕和 / 或車主)

    關聯圖

    file

    關聯細節:

    中間表「drivers」應該儲存駕駛人 ID、駕駛人類型及車輛 ID。
    駕駛是一個模型集合的代稱(Valet 及 Owner),而且不限定兩個模型。駕駛人類型是模型的真正名稱。

    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');
    });
    

    儲存紀錄:

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

    取得紀錄:

    // 取得 driver(Valet / Owner)的 Cars
    $valet->cars
    $owner->cars
    
    // 取得 Car 的 drivers(Valet 及 Owner)
    $car->owners
    $car->valets
    

    file

    更多现代化 PHP 知识,请前往 Laravel / PHP 知识社区

    相关文章

      网友评论

        本文标题:Laravel Eloquent 模型关联速查表

        本文链接:https://www.haomeiwen.com/subject/aptzbftx.html