我有很多很多很难让一个非常嵌套的关系在laravel中正常工作。
想要的行为如下,
我按ID选择一个活动,我想知道哪些人订阅了它。 现在问题是事件和人之间有一些表格。
这是有效的查询!
SELECT persons.id,
persons.firstname,
persons.lastname,
event_scores.score
FROM events
JOIN cities
ON cities.id = events.city_id
JOIN companies
ON cities.id = companies.city_id
JOIN persons
ON companies.id = persons.company_id
JOIN event_scores
ON event_scores.person_id = persons.id
WHERE event_scores.event_id = 1
GROUP BY persons.id
class Event extends Eloquent
{
protected $table = 'events';
public function city()
{
return $this->belongsTo('City');
}
}
class City extends Eloquent
{
protected $table = 'cities';
public function companies()
{
return $this->hasMany('Company');
}
public function event()
{
return $this->hasMany('Event');
}
}
class Company extends Eloquent {
protected $table = 'companies';
public function persons()
{
return $this->hasMany('Person');
}
public function city()
{
return $this->belongsTo('City');
}
}
class Person extends Eloquent
{
protected $table = 'persons';
public function company()
{
return $this->belongsTo('Company');
}
public function eventscore()
{
return $this->belongsToMany('Event', 'event_scores', 'person_id', 'event_id')
->withPivot('score')
->withTimestamps();
}
}
return Event::with('city')->with('company')->get();
和
return Event::with('city')
->whereHas('companies', function($query) use ($company_id){
$query->where('company_id', $company_id);
})->get();
还有很多其他的可能性,我真的坚持这个。在laravel中实现这种嵌套关系链接是否如此困难?
谢谢!
答案 0 :(得分:73)
return Event::with('city.companies.persons')->get();
如果您只想从persons
表中选择某些字段,请使用:
return Event::with(['city.companies.persons' => function ($query) {
$query->select('id', '...');
}])->get();
答案 1 :(得分:15)
对于城市和公司特定领域,您需要分发具有说服力的人。 例如:
return Event::with([
'city' => function ($query) {
$query->select('id', '...');
},
'city.companies' => function ($query) {
$query->select('id', '...');
},
'city.companies.persons' => function ($query) {
$query->select('id', '...');
}
])->get();
答案 2 :(得分:1)
我为以下情况创建了HasManyThrough
关系:Repository on GitHub
安装后,您可以像这样使用它:
class Event extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function persons() {
return $this->hasManyDeep(
Person::class,
[City::class, Company::class],
['id'],
['city_id']
);
}
}
您可以使用withIntermediate()
从中间表中获取属性:
public function persons() {
return $this->hasManyDeep(
Person::class,
[City::class, Company::class],
['id'],
['city_id']
)->withIntermediate(City::class, ['id', '...']);
}
答案 3 :(得分:0)
扩展@ rashmi-nalwaya的答案。我通过一些调整将其用于5.8项目。
我的示例有些不同,因为我试图引用hasOne关系,而不是hasMany。
因此,作为参考,域属于一个网站,而该网站属于一台服务器。我只想从所有这些表中返回某些列。我必须这样做。
Domain::with([
'website' => function($q){
$q->select('id', 'server_id');
},
'website.server' => function($q){
$q->select('id', 'hostname', 'nickname');
}
])
->select('id', 'website_id', 'domain')
->get();
必须确保我可以随时通过我所使用的表的主键(因此,我的情况是id
),其次,我要尝试的相关表的外键到达,得到。因此,website_id
来自域,server_id
来自网站。然后效果很好。
在我的代码中,除此以外,在主域上还有一个where子句。
答案 4 :(得分:0)
return Event::with(['city:id,name', 'city.companies:id,name', 'city.companies.persons:id,name'])->get();