Возможно ли определить полиморфную связь через разные пути (промежуточная модель) в моделях Laravel?

#php #laravel #eloquent #eloquent-relationship #has-many-polymorphs

#php #laravel #красноречивый #красноречивое отношение #имеет много полиморфов

Вопрос:

У меня есть модели «Оплата», «Оценка» и «Цитата», платеж имеет полиморфную связь, в которой он может принадлежать либо цитате, либо оценке, одновременно у цитаты может быть много оценок, поэтому оценка всегда будет принадлежать цитате.

По сути, все платежи всегда будут относиться к котировке, иногда напрямую, а иногда через оценку:

 quotes:
    id 

estimates:
    id
    quote_id 

payments:
    id 
    paymentable_id 
    paymentable_type ("AppModelsQuote" or "AppModelsEstimate")
 

Мой вопрос в том, как я могу определить отношения, чтобы при использовании $quote->payments возвращались не только платежи, которые напрямую связаны с предложением, но и платежи, связанные с оценками, которые принадлежат этому предложению.

Есть предложения? Заранее спасибо.

Ответ №1:

да, это возможно, вы можете попробовать что-то вроде приведенного ниже:

определите три вида отношений:

сначала для прямой оплаты следующим образом:

 public function directPayments(){
    return $this->morphMany(Payment::class,"paymentable");
}
 

и еще один для получения косвенных ссылок с помощью hasManyThrough:

 /**
* returns models, not relation 
*/
public function indirectPayments(){
    return  $this->hasManyThrough(
                                    Payment::class,
                                    Estimate::class,
                                    'quote_id',
                                    'paymentable_id',
                                    'id',
                                    'id')
                  ->where('paymentable_type',"AppModelsEstimate");
}
 

и у вас может быть функция для их агрегирования

 public function getPaymentsAttribute(){
//merge or union in collections
    return $this->directPayments->union($this->indirectPayments()->get());
}
 

Комментарии:

1. Спасибо, похоже, это может быть лучшим решением

2. tnx для принятия / повышения. если в моем ответе есть какие-либо синтаксические / семантические проблемы () , дайте мне знать. чтобы исправить мой ответ