条件Eloquent关系可写不可读(eager load)
Conditional Eloquent relationship can be written but can't be read (eager load)
使用 Laravel 5.3,我的 Order
Eloquent 模型中有一个方法 returns belongsToMany
或 hasMany
关系取决于关于 type
char 属性值的值。
Order
本身是 MasterOrder
模型的子对象,作为一对多关系。
---------------
* MasterOrder *
-------+-------
|
O2M
|
+----------------+------------------+
| | |
----+------- ----+------- -----+------
* Order * * Order * * Order *
* Type = O * * Type = C * * Type = S *
-+---------- -+---------- -+----------
| Offer |CreditPack | Shipment
| | |
M2M M2M O2M
Order
模型中的关系如下
public function items()
{
$types = [
'S' => Shipment::class,
'O' => Discount::class,
'C' => CreditPack::class
];
if ($this->type == 'C') {
return $this->belongsToMany($types['C'], 'credit_pack_order')
->withTimestamps();
}
if ($this->type == 'O') {
return $this->belongsToMany($types['O'], 'discounts')
->withTimestamps();
}
return $this->hasMany($types[$this->type]);
}
插入数据时,我可以使用我的 items()
方法 attach()
报价和积分包,以及 create()
发货,并且没有任何问题。
数据保存在数据库中,一切都在我需要的地方。
问题是,如果我急切地从 MasterOrder
模型开始加载我的关系(即使我在插入数据时从那里开始),我无法通读 items()
。
我可以读取 Order
急于从 MasterOrder
加载它的数据,但是 它在尝试加载时似乎无法读取 Order
属性 items()
.
它能够读取它们,相反,如果我从 Order
开始。
我可以做些什么来避免为每个订单查询两次数据库吗?
谁能解释一下为什么会这样?
我在意大利开发者 Facebook 群组中讨论这个问题时终于找到了解决方法。
基本上我可以告诉方法 type
从订单中得到什么作为函数的参数。这样即使它没有加载属性,它也会知道该回答什么。
关系变为:
public function items($type = null)
{
if ($type != null) {
$this->type = $type;
}
$types = [
'S' => Shipment::class,
'O' => Discount::class,
'C' => CreditPack::class
];
if ($this->type == 'C') {
return $this->belongsToMany($types['C'], 'credit_pack_order')
->withTimestamps();
}
if ($this->type == 'O') {
return $this->belongsToMany($types['O'], 'discounts')
->withTimestamps();
}
return $this->hasMany($types[$this->type]);
}
我使用
检索数据
$masterorder = auth()->user()->orders() // orders() is a User->MasterOrder
->where('reference', '=', $reference) // hasMany relation
->first();
$details = $masterorder->orders()->get()
->map(function ($order) {
$order->items = $order->items($order->type)->get()->toArray();
return $order;
});
使用 Laravel 5.3,我的 Order
Eloquent 模型中有一个方法 returns belongsToMany
或 hasMany
关系取决于关于 type
char 属性值的值。
Order
本身是 MasterOrder
模型的子对象,作为一对多关系。
---------------
* MasterOrder *
-------+-------
|
O2M
|
+----------------+------------------+
| | |
----+------- ----+------- -----+------
* Order * * Order * * Order *
* Type = O * * Type = C * * Type = S *
-+---------- -+---------- -+----------
| Offer |CreditPack | Shipment
| | |
M2M M2M O2M
Order
模型中的关系如下
public function items()
{
$types = [
'S' => Shipment::class,
'O' => Discount::class,
'C' => CreditPack::class
];
if ($this->type == 'C') {
return $this->belongsToMany($types['C'], 'credit_pack_order')
->withTimestamps();
}
if ($this->type == 'O') {
return $this->belongsToMany($types['O'], 'discounts')
->withTimestamps();
}
return $this->hasMany($types[$this->type]);
}
插入数据时,我可以使用我的 items()
方法 attach()
报价和积分包,以及 create()
发货,并且没有任何问题。
数据保存在数据库中,一切都在我需要的地方。
问题是,如果我急切地从 MasterOrder
模型开始加载我的关系(即使我在插入数据时从那里开始),我无法通读 items()
。
我可以读取 Order
急于从 MasterOrder
加载它的数据,但是 它在尝试加载时似乎无法读取 Order
属性 items()
.
它能够读取它们,相反,如果我从 Order
开始。
我可以做些什么来避免为每个订单查询两次数据库吗?
谁能解释一下为什么会这样?
我在意大利开发者 Facebook 群组中讨论这个问题时终于找到了解决方法。
基本上我可以告诉方法 type
从订单中得到什么作为函数的参数。这样即使它没有加载属性,它也会知道该回答什么。
关系变为:
public function items($type = null)
{
if ($type != null) {
$this->type = $type;
}
$types = [
'S' => Shipment::class,
'O' => Discount::class,
'C' => CreditPack::class
];
if ($this->type == 'C') {
return $this->belongsToMany($types['C'], 'credit_pack_order')
->withTimestamps();
}
if ($this->type == 'O') {
return $this->belongsToMany($types['O'], 'discounts')
->withTimestamps();
}
return $this->hasMany($types[$this->type]);
}
我使用
检索数据$masterorder = auth()->user()->orders() // orders() is a User->MasterOrder
->where('reference', '=', $reference) // hasMany relation
->first();
$details = $masterorder->orders()->get()
->map(function ($order) {
$order->items = $order->items($order->type)->get()->toArray();
return $order;
});