2017-02-05 2 views
0

У меня есть три таблицы:Не удается получить hasManyThrough работать

nCompanies (model Company) 
nTransactions (model Transaction) 
nBrokers (model Broker) 

Одна компания может иметь большое количество операций Один брокера может иметь много сделок

компании и посредник не имеет отношения ,

Теперь я хотел бы получить список брокеров для каждой компании через транзакции компании. Для этого я думал, что hasManyThrough() выполнит эту работу. Но я не могу заставить его работать.

В моей модели компании у меня есть это:

class Company extends Model 
{ 
    protected $table = 'nCompanies'; 
    protected $primaryKey = 'nCompanyId'; 

    public function transactions() 
    { 
     return $this->hasMany('App\Transaction', 'nCompanyId'); 
    } 

    public function brokers() 
    { 
     //This does not work 
     return $this->hasManyThrough('App\Broker', 'App\Transaction', 'nCompanyId', 'nBrokerId'); 
    } 

} 

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

$companies = DB::table('nCompanies') 
      ->join('nTransactions', 'nCompanies.nCompanyId', '=', 'nTransactions.nCompanyId') 
      ->join('nBrokers', 'nTransactions.nBrokerId', '=', 'nBrokers.nBrokerId') 
      ->selectRaw('nBrokers.*, nCompanies.*) 
      ->groupBy('nCompanies.nCompanyId', 'nBrokers.nBrokerId') 
      ->get(); 

Как я могу это решить? Должен ли я использовать что-то другое вместо hasManyThrough?

ответ

0

HasManyThrough здесь не работает, потому что отношения между транзакцией и брокером неверны: хотя существует связь HasMany Company-> Transaction, существует только транзакция HasOne Transaction-> Broker. Для HasManyThrough для работы, оба должны быть HasMany, хотя.

Предлагаемое решения было бы использовать аксессор вместе с подзапросом в вашей модели, как это:

public function getBrokersAttribute() 
{ 
    $transactionIds = $this->transactions->groupBy('nBrokerId')->lists('nBrokerId'); 
    return Broker::find($transactionIds); 
} 

Имейте в виде, что это приведет к двум отдельным запросам, хотя Laravel бы кэшировать результат $transactionIds после первой загрузки. Кроме того, это решение не поддерживает загрузку и не рекомендуется при работе со многими компаниями.

В качестве альтернативы можно использовать некоторое зацикливание, чтобы сохранить способность нетерпеливой загрузки:

public function getBrokersAttribute() 
{ 
    $brokers = new Collection(); 
    foreach ($this->transactions as $transaction) { 
     if (!$brokers->contains($transaction->broker->nBrokerId)) { 
      $brokers->add($transaction->broker); 
     } 
    } 
    return $brokers; 
} 

В этом примере вы можете нетерпеливые нагрузки с помощью ->with('transactions.broker').

+0

Спасибо! Оно работает – Josef

0

Я перечитал ваш вопрос и понял, что вы хотите получить брокеров и компании через транзакцию. Я думаю, у вас уже есть nCompanyId и nBrokerId в таблице транзакций. Тогда я думаю, что брокеры должны быть доступны в Transaction модели, то, так что вы можете иметь:

class Transaction extends Model 
{ 
    public function brokers() 
    { 
     return $this->hasMany('App\Broker', 'nBrokerId'); 
    } 
} 

Таким образом, вы можете назвать его:

$brokers = Company::find(1)->transactions->where('id', '1')->brokers(); 

Это просто пример моих мыслей по этому поводу хотя:

Я не знаю, поможет ли это вам получить то, что вы пытаетесь сделать. :)

+0

Спасибо, но я хочу список брокеров для каждой компании. Поэтому для компании X я хотел бы показать всех отдельных брокеров, которые совершили транзакции для этой компании. – Josef

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