Laravel 8 多表关系
Posted
技术标签:
【中文标题】Laravel 8 多表关系【英文标题】:Laravel 8 Multiple Table Relationship 【发布时间】:2021-11-18 03:45:08 【问题描述】:这是一个很长的帖子,提前抱歉。
我有几个关于下图的问题。
-
如何为这些表创建关系? (试过“belongsToMany”和“hasMany”)
我应该使用 Eloquent 还是 Query Builder 来获得想要的结果? (图片附在下面以获得所需的结果)
“client_order_items”是数据透视表吗?
如何区分数据透视表?是不是因为表有多个
外键?
如何从“Manufacturer”模型访问“images”表? “hasOneThrough / hasManyThrough”可以实现这一点吗?
仅使用 Eloquent 或 DB Query 是否可以达到预期的结果?
//sample:
Manufacturers::find(2)->client_order_items->cars->images->car_image
我尝试将“client_order_items”视为数据透视表,然后在“Manufacturer”、“Car”和“Car”中使用“belongsToMany”建立关系“ClientOrder”模型。
// App\Model\Manufacturer.php
public function client_orders()
return $this->belongsToMany(ClientOrder::class,
"client_order_items", "manufacturer_id", "client_order_id")
->withPivot('id', 'quantity', 'car_id');;
public function cars()
return $this->belongsToMany(Car::class,
"client_order_items", "manufacturer_id", "car_id");
// App\Model\Car.php
public function client_orders()
return $this->belongsToMany(ClientOrder::class,
"client_order_items", "car_id", "client_order_id");
public function manufacturers()
return $this->belongsToMany(Manufacturer::class,
"client_order_items", "car_id", "manufacturer_id");
// App\Model\ClientOrder.php
public function cars()
return $this->belongsToMany(Manufacturer::class,
"client_order_items", "client_order_id", "car_id");
public function manufacturers()
return $this->belongsToMany(Manufacturer::class,
"client_order_items", "client_order_id", "manufacturer_id");
我也尝试过“hasMany”关系:
// App\Model\Manufacturer.php
public function client_order_items()
return $this->hasMany(ClientOrderItems::class);
// App\Model\Cars.php
public function client_order_items()
return $this->hasMany(ClientOrderItems::class);
// App\Model\ClientOrder.php
public function client_order_items()
return $this->hasMany(ClientOrderItems::class);
// App\Model\ClientOrderItems.php
public function car()
return $this->belongsTo(Car::class);
public function manufacturer()
return $this->belongsTo(Manufacturer::class);
public function client_order()
return $this->belongsTo(ClientOrder::class);
如果我做了这样的事情,我的目标是得到结果:
// Manufacturer::find(2)->client_orders
// Desired Result:
[
"client_order_id": 88062,
"first_name": "Clark",
"last_name": "Kent",
"order_items": [
"client_order_item_id": 37394,
"quantity": 1,
"car_id": 68,
"image": "path_img1"
]
,
"client_order_id": 60978,
"first_name": "Bruce",
"last_name": "Wayne",
"order_items": [
"client_order_item_id": 79913,
"quantity": 1,
"car_id": 68,
"image": "path_img1"
,
"client_order_item_id": 84743,
"quantity": 1,
"car_id": 95,
"image": "path_img2"
]
]
但我目前得到的结果(使用“belongsToMany”)是:
// Manufacturer::find(2)->client_orders
// Current Result:
[
"id": 88062,
"first_name": "Clark",
"last_name": "Kent",
"pivot":
"manufacturer_id": 2,
"client_order_id": 88062,
"id": 37394,
"quantity": 1,
"car_id": 68
,
"id": 60978,
"first_name": "Bruce",
"last_name": "Wayne",
"pivot":
"manufacturer_id": 2,
"client_order_id": 60978,
"id": 79913,
"quantity": 1,
"car_id": 68
,
"id": 60978,
"first_name": "Bruce",
"last_name": "Wayne",
"pivot":
"manufacturer_id": 2,
"client_order_id": 60978,
"id": 84743,
"quantity": 1,
"car_id": 95
]
再次为这篇长文感到抱歉。 提前谢谢你。
【问题讨论】:
【参考方案1】:经过几个小时的实验和阅读,我得到了我想要的结果。
建立关系:
Manufacturer 模型与“ClientOrder”具有“belongsToMany”关系
// App\Model\Manufacturer
public function client_orders()
return $this->belongsToMany(ClientOrder::class, 'client_order_items', 'manufacturer_id', 'client_order_id');
“Car”和“Image”模型具有“hasMany”关系。这将使我们能够从“ClientOrderItems”模型访问“Image”模型。
// App\Models\Car
public function image()
return $this->belongsTo(Image::class);
// App\Models\Image
public function cars()
return $this->hasMany(Car::class);
为模型创建访问器
在“ClientOrder”模型中,为“order_items”键创建一个访问器。这将从“OrderLineItems”中获取与“manufacturer_id”和“client_order_id”相关的行。
// App\Models\ClientOrder
protected $appends = ["order_items"];
public function getOrderItemsAttribute()
$items = ClientOrderItems::where("manufacturer_id", '=', $this->pivot->manufacturer_id)
->where("client_order_id","=",$this->pivot->client_order_id)
->select(["id as client_order_item_id","car_id","quantity"])
->get();
return $items;
在“ClientOrderItems”枢轴模型中,为“图像”创建一个访问器。
// App\Models\ClientOrderItems
protected $appends = ["image"];
public function getImageAttribute()
return Car::find($this->car_id)->image->car_image;
上面 2 个代码的结果如下所示:
[
"client_order_item_id": 79913,
"quantity": 1,
"car_id": 68,
"image": "path_img1"
,
"client_order_item_id": 84743,
"quantity": 1,
"car_id": 95,
"image": "path_img2"
]
有关访问器和突变器的更多信息: https://laravel.com/docs/8.x/eloquent-mutators#accessors-and-mutators
检索记录
要获取与manufacturer_id相关的“客户订单”,请使用:
/// App\Http\Controllers\ManufacturerController;
public function index()
$client_order = Manufacturer::find($manufacturer_id)->client_orders->unique("id")->values();
上面的代码只会从“client_orders”表中获取唯一的行。在访问器的帮助下为每一行附加相关的“order_items”。
[
"client_order_id": 88062,
"first_name": "Clark",
"last_name": "Kent",
"order_items": [
"client_order_item_id": 37394,
"quantity": 1,
"car_id": 68,
"image": "path_img1"
]
,
"client_order_id": 60978,
"first_name": "Bruce",
"last_name": "Wayne",
"order_items": [
"client_order_item_id": 79913,
"quantity": 1,
"car_id": 68,
"image": "path_img1"
,
"client_order_item_id": 84743,
"quantity": 1,
"car_id": 95,
"image": "path_img2"
]
]
【讨论】:
以上是关于Laravel 8 多表关系的主要内容,如果未能解决你的问题,请参考以下文章