编程

Laravel 关联 - hasOneThrough() 和 hasManyThrough()

338 2024-10-06 16:18:00

你可能在 Laravel 项目中用过 hasOnehasManybelongsTobelongsToMany 关联。除此之外, Laravel 提供 hasOneThroughhasManyThrough 关联。它们非常适合访问嵌套关系,而不会带来额外的麻烦。让我们把它分解一下。

想象一下,你有一个项目管理应用,其中包含以下表格: 

  1. Users: 代表系统中的用户。
  2. Projects: 每个用户可以有多个项目。
  3. Tasks: 每个项目可以有多个任务。
  4. 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;

它获取了它碰到的第一个任务的状态(基于数据库查询排序)。

总结

hasOneThroughhasManyThrough 关联可以简化代码,轻松访问深度嵌套的关联。它们非常适合需要跨越多个层次关联的场景。