条件Eloquent关系可写不可读(eager load)

Conditional Eloquent relationship can be written but can't be read (eager load)

使用 Laravel 5.3,我的 Order Eloquent 模型中有一个方法 returns belongsToManyhasMany 关系取决于关于 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;
    });