我有三张桌子:
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 :(得分: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();
这只是我对此的看法的一个例子:
我不知道这是否有助于你得到你想要做的事情。 :)
答案 1 :(得分:0)
HasManyThrough在这里不起作用,因为Transaction和Broker之间的关系是错误的:虽然有一个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')
急切加载。