Laravel 关联 - hasOneThrough() 和 hasManyThrough()
你可能在 Laravel 项目中用过 hasOne
、hasMany
、belongsTo
和 belongsToMany
关联。除此之外, Laravel 提供 hasOneThrough
和 hasManyThrough
关联。它们非常适合访问嵌套关系,而不会带来额外的麻烦。让我们把它分解一下。
想象一下,你有一个项目管理应用,其中包含以下表格:
- Users: 代表系统中的用户。
- Projects: 每个用户可以有多个项目。
- Tasks: 每个项目可以有多个任务。
- Statuses: 每个项目有一个状态 (e.g. pending, completed).
设置模型和关联
接下来,让我们在 Laravel 中定义模型及关联。L
🟡 Project 模型
class Project extends Model
{
public function user()
{
return $this->belongsTo(User::class);
}
public function tasks()
{
return $this->hasMany(Task::class);
}
}
🟡 Task 模型
class Task extends Model
{
public function project()
{
return $this->belongsTo(Project::class);
}
public function status()
{
return $this->hasOne(Status::class);
}
}
🟡 Status 模型
class Status extends Model
{
public function task()
{
return $this->belongsTo(Task::class);
}
}
🔴 User 模型
class User extends Model
{
public function projects()
{
return $this->hasMany(Project::class);
}
public function tasks()
{
return $this->hasManyThrough(Task::class, Project::class);
}
public function status()
{
return $this->hasOneThrough(Status::class, Task::class);
}
}
使用 hasManyThrough
在 User
模型中,我们使用了 hasManyThrough
来获取用户的所有任务,即使任务是直接关联到项目的。下例展示如何使用关联的任务:
$user = User::find(1);
$tasks = $user->tasks;
foreach ($tasks as $task) {
echo $task->name;
}
使用 hasOneThrough
你可以从用户中直接获取任务的状态:
$user = User::find(1);
$status = $user->status;
echo $status->name;
它获取了它碰到的第一个任务的状态(基于数据库查询排序)。
总结
hasOneThrough
和 hasManyThrough
关联可以简化代码,轻松访问深度嵌套的关联。它们非常适合需要跨越多个层次关联的场景。