2016-12-20 3 views
0

Использование Laravel 5.3, у меня есть метод в моих Order красноречивых моделях, которая возвращает belongsToMany или hasMany отношений в зависимости от величины значения атрибута в type полукокса ,Условного Eloquent отношения может быть написано, но не может быть прочитано (нетерпеливые нагрузки)

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 (хотя я и начинаю оттуда, когда я вставляю данные).

Я могу читать Order данные жадную загрузку его из MasterOrder, но кажется, он не может читать Order атрибуты, когда он пытается загрузить items().

Он может читать их, вместо этого, если я начинаю с Order.

Есть ли что-то, что я могу сделать, чтобы дважды не запрашивать базу данных для каждого заказа?
Может ли кто-нибудь объяснить мне, почему это происходит?

+1

Он смотрит на меня, как будто вы можете посмотреть на использование полиморфного отношения на вашей модели - это намекает на то, что вы используете условные обозначения для настройки отношений. – Oddman

+0

@ Oddman Я не могу, одно из отношений отличается от других. «Отгрузка» требует от одного до многих, в то время как другие - как многие, так и многие. – phaberest

+1

Есть один из двух способов, которыми вы можете это сделать: либо иметь отдельные методы для каждой связи (мой предпочтительный метод), либо использовать полиморфные отношения и относиться ко всем этим способом. Проблема заключается в том, что, поскольку у вас есть это, items() возвратит различные коллекции объектов, и это проблема с границей домена. Это не должно быть так. – Oddman

ответ

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; 
    }); 
+1

Я по-прежнему настоятельно рекомендую вам изменить то, что вы здесь делаете - это 3 отдельных отношения и их следует рассматривать как таковые. – Oddman

+0

Я понимаю, что вы имеете в виду, и я благодарю вас за это предложение, но я получил форму в форме, и в этом случае я не хочу разорвать SOLID. Вероятно, я собираюсь реорганизовать в ближайшем будущем. – phaberest

+0

Не уверен, что вы имеете в виду, сломав SOLID, но достаточно справедливо. – Oddman

Смежные вопросы