多个表上的雄辩的自定义“属于”关系

Posted

技术标签:

【中文标题】多个表上的雄辩的自定义“属于”关系【英文标题】:Eloquent custom "belongs to" relationship on multiple tables 【发布时间】:2020-06-23 12:01:14 【问题描述】:

我有以下数据库结构:

车辆:id、car_id、plane_id 表格汽车:id、型号... 表平面:id、型号...

当向Vehicles表添加新记录时,如果是Car,则设置car_id,而plane_id 将留空,反之亦然,我知道这是一个糟糕的结构,但它是遗留的,我无法更改。

所以我想在 Vehicle 模型中定义一个关系,它可以根据哪个键为空,car_idplane_id,检索 Car 对象或 Plane 对象>。顺便说一句,我已经定义了两个关系,分别检索 Car 对象和 Plane 对象。

public function carVehicle()

    return $this->belongsTo(Car::class, 'car_id');


public function planeVehicle()

    return $this->belongsTo(Plane::class, 'plane_id');

【问题讨论】:

那么,您遇到了什么错误?不用保存car_id,plane_id,你可以通过多态关系来管理它。 【参考方案1】:

这最好通过Polymorphic 关系来处理(有关详细信息,请参阅https://laravel.com/docs/5.8/eloquent-relationships#polymorphic-relationship),但是如果您当前的模型与结构不匹配并且您无法更改它,则可以使用其他方法。

您可以使用第三种方法,将两者都添加到 Collection 并返回 first() 之一(因为您说 car_idplane_id 之一将始终是 null):

Vehicle.php:

public function getChildVehicleAttribute()
  return collect([$this->carVehicle, $this->planeVehicle])
  ->filter(function($record) 
    return $record != null;
  )->first();

然后,您将通过以下查询访问:

$vehicle = Vehicle::with(['carVehicle', 'planeVehicle'])->first()->child_vehicle;
// OR
$vehicles = Vehicle::with(['carVehicle', 'planeVehicle'])->get();
foreach($vehicles AS $vehicle)
  $childVehicle = $vehicle->child_vehicle;
  // dd($childVehicle, etc.)

with() 子句会预先加载两个关系,因此$this->carVehicle$this->planeVehicle 不会触发额外的数据库调用,并且在任何Vehicle 实例上调用child_vehicle 将返回Car 或@987654337 @(或null,如果两者都没有定义)

【讨论】:

以上是关于多个表上的雄辩的自定义“属于”关系的主要内容,如果未能解决你的问题,请参考以下文章

laravel 关系集合上的自定义排序

数据类型(字段)表上的雄辩关系

Laravel:如何设置带有条件的自定义列?

自定义表上的大型查询 - 内存问题

同一张表上的多个关系

mysql通过在同一张表上查询的自定义顺序