【问题标题】:Problems when using join and pagination together in Laravel在 Laravel 中同时使用 join 和 pagination 时的问题
【发布时间】:2021-07-19 10:16:15
【问题描述】:

我的数据库中有一些表,我正在尝试在它们之间进行交易。我的目标是在我的项目页面上以卡片的形式显示项目名称和该项目中的员工,如下图所示。 (除了我提到的方法,如果有更好的方法,请大家分享。)

当尝试这样做时,我首先想到的是使用 leftJoin。与这些项目一起,我想到了将那个项目中的用户拉到一起,并使用嵌套的 foreach 来展示他们。 如果我只是想拍摄项目,没有问题,前 4 个项目来了,一切正常。但是由于我需要吸引该项目中的用户以及我的项目,所以当我使用 leftJoin 时,我得到了如下所示的输出。我不得不使用分页,因为我需要每页显示 4 个项目,而当我使用分页时,输入的行不一致。在等待 4 个项目和他们的员工到达时,前 4 行来了。 (一个项目的3名员工和另一个项目的第一名员工到了。)

我的代码:

$query = Project::query();
$query->select('prj_name', 'us_name');
$query->where('up_type_id', 3);
$query->leftJoin('user_positions', 'projects.prj_id', '=', 'user_positions.up_source_id');
$query->leftJoin('users', 'user_positions.up_user_id', '=', 'users.us_id');
$data['projectList'] = $query->paginate(4)->toArray();
return view('pages.projects.index', $data);

输出:

[data] => Array
        (
            [0] => Array
                (
                    [prj_name] => Project Name - 2
                    [us_name] => Tracey Dyer
                )

            [1] => Array
                (
                    [prj_name] => Project Name - 2
                    [us_name] => Joseph Dickens
                )

            [2] => Array
                (
                    [prj_name] => Project Name - 2
                    [us_name] => Steven Ogden
                )

            [3] => Array
                (
                    [prj_name] => Project Name - 3
                    [us_name] => Warren Nash
                )

        )

我的桌子:

其他信息: 它与我的问题没有直接关系,但我想说明它以供参考。我的名为“user_position_types”的表代表公司内的字段。 “user_positions”表中的“up_type_id”列指定了分区类型(如Department、Project)。 如果该列为1,则表示部门,“source_id”表示是哪个部门。如果是3,则表示项目,“source_id”再次表示它是哪个项目。

我要感谢所有提前回答的人。

【问题讨论】:

    标签: php mysql laravel join relational-database


    【解决方案1】:

    您可以考虑使用 Eloquent 关系而不是左连接。实际上,在您的情况下,左联接不会那么好用,因为您必须在之后将同一项目中的所有用户从行中分组。使用whereHaswith的Eloquent关系示例如下。

    $data['projectList'] = Project::select('prj_name', 'us_name')
        ->whereHas('users, function($query) {
            $query->where('users_positions.up_type_id', 3);
        })
        ->with('users')
        ->paginate(4);
    

    whereHas 部分仅过滤具有users 关系的项目,并且具有枢轴字段up_type_id 3。
    with部分会加载项目对应的用户。

    您还需要在Project 模型中添加users 关系。

    public function users()
    {
        return $this->belongsToMany(User::class, 'user_positions', 'prj_id', 'us_id')
            ->withPivot('up_type_id');
    }
    

    这样你就可以像这样展示你的项目和用户了。

    foreach($data['projectList'] as $project) {
        $project->prj_name;
        foreach($project->users as $user) {
            $user->us_name;
        }
    }
    

    如果您希望拥有没有用户的项目和用户来自 up_type_id = 3 的项目,您可以使用 where 闭包并从这两个条件中过滤(使用 orWhereHas)。

    $data['projectList'] = Project::select('prj_name', 'us_name')
        ->where(function ($query) {
            $query->doesntHave('users')
                ->orWhereHas('users, function($query) {
                    $query->where('user_positions.up_type_id', 3);
                });
        })
        ->with('users')
        ->paginate(4);
    

    【讨论】:

    • 非常感谢您的回答。我兴奋地立即尝试,但得到了这样的错误。我想知道我在哪里做错了: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'pivot' in 'where clause' (SQL: select count(*) as aggregate from projects where exists (select * from @987654336 @inner join user_positions on users.us_id = user_positions.up_user_id where projects.prj_id = user_positions.user_positions.up_source_id and pivot = up_id)))
    • 这很奇怪,Pivot 应该在中间表中查找字段,而不是数据透视字段。 laravel.com/docs/8.x/…,你用的是什么版本的 Laravel?
    • 我使用的是 Laravel 8 版本。
    • 我认为解决方法可能是 $query->where('user_positions.up_type_id', 3);
    • 非常感谢。绝对正确的答案。非常感谢你。最后,这将是我想问的最后一件事。您传输的代码工作正常,但只返回带有用户的项目。由于我需要查看没有用户的项目,我应该如何进行更改?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-31
    • 2011-10-18
    • 2019-08-23
    • 1970-01-01
    • 2017-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多