hasManyThrough 与变形
hasManyThrough with morph
我有一个项目 table 可以分配给用户或团队,这是结构:
id
assignable_id
assignable_type
class Project extends Model {
public function assignable(): MorphTo
{
return $this->morphTo();
}
}
我的团队 table 包含具有关键点的成员 table:
id
class Team extends Model {
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
public function projects(): MorphMany
{
return $this->morphMany(Project::class, 'assignable');
}
}
// team_user table
team_id
user_id
最后是我的用户 table:
id
class User extends Model {
public function teams(): BelongsToMany
{
return $this->belongsToMany(Team::class);
}
public function projects(): MorphMany
{
return $this->morphMany(Project::class, 'assignable');
}
}
现在的问题是我想得到所有直接或通过团队分配给用户的项目,正如预期的那样 $user()->projects return 直接分配的项目给用户。
我尝试了很多解决方案,但 none 对我有用。
所以你实际上需要这样的东西:
public function project()
{
return $this->hasManyThrough('App\Project', 'App\User', 'assignable_id')
->where(
'assignable_type',
array_search(static::class, Relation::morphMap()) ?: static::class
);
}
或
public function project()
{
return $this->belongsToMany(Project::class, 'assignable', 'assignable_id', 'project_id')
->where('assignable_type', static::class);
}
参考:Laravel Polymorphic Relations Has Many Through
您的工作解决方案:
public function projects() {
return $this->hasManyThrough(
Project::class,
User::class,
'id',
'assignable_id',
)->where(
'assignable_type', User::class
)->orWhere(function ($q) {
$q->where('assignable_type', Team::class)
->whereIn('assignable_id', $this->teams->pluck('id'));
});
}
使用whereHasMorph
:
$user = ...
$projects = Project::whereHasMorph(
'assignable',
[Team::class, User::class],
function ($query, $type) use($user) {
if($type === Team::class){
$query->whereRelation('users', 'id', $user->id);
}else{
$query->where('id', $user->id);
}
}
)->get();
或拆分成 2 个查询并合并在一起:
$projects = $user->projects;
$teams = $user->teams()->with('projects')->get();
$teams_projects = $teams->pluck('projects')->collapse();
$projects = $projects->merge($teams_projects);
我有一个项目 table 可以分配给用户或团队,这是结构:
id
assignable_id
assignable_type
class Project extends Model {
public function assignable(): MorphTo
{
return $this->morphTo();
}
}
我的团队 table 包含具有关键点的成员 table:
id
class Team extends Model {
public function users(): BelongsToMany
{
return $this->belongsToMany(User::class);
}
public function projects(): MorphMany
{
return $this->morphMany(Project::class, 'assignable');
}
}
// team_user table
team_id
user_id
最后是我的用户 table:
id
class User extends Model {
public function teams(): BelongsToMany
{
return $this->belongsToMany(Team::class);
}
public function projects(): MorphMany
{
return $this->morphMany(Project::class, 'assignable');
}
}
现在的问题是我想得到所有直接或通过团队分配给用户的项目,正如预期的那样 $user()->projects return 直接分配的项目给用户。
我尝试了很多解决方案,但 none 对我有用。
所以你实际上需要这样的东西:
public function project()
{
return $this->hasManyThrough('App\Project', 'App\User', 'assignable_id')
->where(
'assignable_type',
array_search(static::class, Relation::morphMap()) ?: static::class
);
}
或
public function project()
{
return $this->belongsToMany(Project::class, 'assignable', 'assignable_id', 'project_id')
->where('assignable_type', static::class);
}
参考:Laravel Polymorphic Relations Has Many Through
您的工作解决方案:
public function projects() {
return $this->hasManyThrough(
Project::class,
User::class,
'id',
'assignable_id',
)->where(
'assignable_type', User::class
)->orWhere(function ($q) {
$q->where('assignable_type', Team::class)
->whereIn('assignable_id', $this->teams->pluck('id'));
});
}
使用whereHasMorph
:
$user = ...
$projects = Project::whereHasMorph(
'assignable',
[Team::class, User::class],
function ($query, $type) use($user) {
if($type === Team::class){
$query->whereRelation('users', 'id', $user->id);
}else{
$query->where('id', $user->id);
}
}
)->get();
或拆分成 2 个查询并合并在一起:
$projects = $user->projects;
$teams = $user->teams()->with('projects')->get();
$teams_projects = $teams->pluck('projects')->collapse();
$projects = $projects->merge($teams_projects);