我的架构如下:
客户(有许多帐户)
- ID
- 姓名
帐户(拥有许多持股,属于客户)
- id(整数)
- account_id(字符串,唯一键)
- 姓名
持股(属于账户)
- ID
- account_id(字符串)
- 值(value)
- 持有日期...等
因此,客户拥有许多账户和许多 Assets 。需要注意的是,帐户的本地 key 是 account_id
,而不仅仅是预期的 id
。这是因为帐户需要具有字符串标识符。在馆藏表中,外键也是 account_id
。
我已经这样定义了我的关系:
// Client.php
public function accounts()
{
return $this->hasMany('Account');
}
// Account.php
public function client()
{
return $this->belongsTo('Client');
}
public function holdings()
{
return $this->hasMany('Holding');
}
// Holding.php
public function account()
{
return $this->belongsTo('Account', 'account_id', 'account_id');
}
如果我想查询给定客户端 ID 的所有馆藏,我该怎么做?如果我做类似的事情
Client::find($id)->accounts->holdings;
我收到此错误:
Undefined property: Illuminate\Database\Eloquent\Relations\HasMany::$holdings
我还尝试使用 hasManyThrough 关系(已将关系添加到我的模型中),但似乎只有一种方法来定义外键,而不是帐户的本地键。有什么建议吗?
最佳答案
假设您的帐户表中有 client_id
,
这样做:
// Account model
public function holdings()
{
return $this->hasMany('Holding', 'account_id', 'account_id');
}
// then
$client = Client::with('accounts.holdings')->find($id);
$client->accounts // collection
->first() // or process the collecction in the loop
->holdings; // holdlings collection
HasManyThrough
仅当 Account
模型已(或为此目的)将 $primaryKey 设置为 account_id
而不是默认的 时才起作用>id
由于 account_id
不是 Account
模型的主键,因此您不能使用 hasManyThrough
。所以我建议你这样做:
$accountIds = $client->accounts()->lists('account_id');
// if it was many-to-many you would need select clause as well:
// $accountIds = $client->accounts()->select('accounts.account_id')->lists('account_id');
$holdings = Holding::whereIn('account_id', $accountIds)->get();
这样你就可以得到你想要的集合,与急切加载相比,还需要 1 个查询。
关于php - Laravel hasManyThrough 与非默认本地键的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23826110/