有条件的雄辩关系可以写,但无法读取(急切加载)

时间:2016-12-20 11:12:15

标签: laravel eloquent relationships

使用Laravel 5.3,我的Order Eloquent模型中有一个方法,根据belongsToMany char属性值的值返回hasManytype关系。

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

在插入数据时,我可以使用我的attach()方法create()商品和信用包以及items()货件,而且无任何问题。 数据保存在数据库中,一切都在我需要的地方。

问题是,如果我急切地从items()模型开始加载我的关系,我就无法通读MasterOrder(即使我在插入数据时从那里开始)。< / p>

我可以阅读Order数据从MasterOrder急切加载,但似乎在尝试加载{{1}时无法读取Order个属性}}

如果我从items()开始,则能够阅读它们。

我是否可以做些什么来避免每个订单两次查询数据库? 有人可以解释一下为什么会这样吗?

1 个答案:

答案 0 :(得分:0)

我在意大利开发商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;
    });