【问题标题】:Laravel HasOneThrough RelationshipLaravel HasOneThrough 关系
【发布时间】:2020-10-24 01:42:43
【问题描述】:

我在 Laravel 应用程序中设置了以下数据库架构。为简单起见,我只提及重要的列。

任务

  • job_id

工作

  • client_id

用户

  • 身份证

在 Task 模型中,我希望有一个与 users 表的关系方法,在本例中称为中间 jobs 表上的 Client (client_id)。

在我的代码中,我希望能够引用$task->client();

我查看了文档并发现:

public function client()
{
    return $this->belongsToMany('App\User', 'users', 'client_id');
}

返回:

"SQLSTATE[42S22]: 未找到列:1054 未知列 'jobs.user_id' 在“字段列表”中(SQL:选择users.*、jobs.client_id 作为 pivot_client_id, jobs.user_id 作为pivot_user_id 来自users 内部连接jobsusers.id = jobs.user_id 其中 jobs.client_id = 112 和 users.deleted_at 为空)"

public function client()
{
    return $this->hasOneThrough('App\User', 'App\Job', 'client_id', 'user_id');
}

返回:

"SQLSTATE[42S22]: 未找到列:1054 未知列 'on 子句'中的'users.user_id'(SQL:选择users.*, jobs.client_id as laravel_through_key from users 内部连接 jobs on jobs.id = users.user_id 其中jobs.deleted_at 是 空和jobs.client_id = 111 和users.deleted_at 为空 限制 1)"

如何从Task 模型中检索User 模型?

【问题讨论】:

    标签: php sql database laravel eloquent


    【解决方案1】:

    您可以尝试以下方法吗:

    public function client()
    {
        return $this->hasOneThrough('App\User', 'App\Job', 'id', 'id', 'id', 'client_id');
    }
    

    【讨论】:

    • 不幸返回 null
    • 那么可能最好使用DB::enableQueryLog();DB::getQueryLog(),这样您就可以确定生成的查询的哪一部分是错误的。
    • 我针对以下问题测试了我的解决方案:Task 属于 JobUser 属于 User
    【解决方案2】:

    对于仍在寻找有效答案的人:

    在您的 Task 模型类中:

    public function client()
    {
        return $this->hasOneThrough(
            User::class, // 'App\User' or 'App\Models\User' in Laravel 8
            Job::class, // 'App\Job' or 'App\Models\Job' in Laravel 8
            'id', // Foreign key on the jobs table...       <--,
            'id', // Foreign key on the users table...         |    <--,
            'job_id', // Local key on the tasks table...    ---'       |
            'client_id' // Local key on the jobs table...           ---'
        );
    }
    

    箭头显示哪一列用于链接到另一列。

    正确的引用总是让我困惑一分钟,所以希望这会有所帮助。 :)

    参考见Has One Through - Key conventions

    在实践中:

    当您运行 Task::with(['client'])-&gt;first() 时,框架会运行 2 个 SQL 查询:

    select * from `tasks`
    

    从这些结果行中提取所有唯一的 job_ids 以用于第二个 SQL 的绑定 (?):

    select
        `users`.*,
        `jobs`.`id` as `laravel_through_key`
    from `users`
    inner join `jobs`
        on `jobs`.`client_id` = `users`.`id`
    where `jobs`.`id` in (?, ? ...etc)
    

    使用 MySQL 使用 Laravel 8.47.0 进行测试。

    【讨论】:

      猜你喜欢
      • 2023-02-04
      • 1970-01-01
      • 2020-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      相关资源
      最近更新 更多