【问题标题】:Laravel Nested Query in Many to Many Relationship from within Blade Template刀片模板中的多对多关系中的 Laravel 嵌套查询
【发布时间】:2020-11-08 14:23:45
【问题描述】:

我试图根据角色隔离不同的团队成员,在刀片视图的 $teams 中将它们过滤为 $team @foreach 循环。输出将是具有给定角色的团队成员的简单列表。几天来,我一直在网上寻找线索,我确信答案就在我面前——我只是还没有看到。理想情况下,我希望能够使 api 流在逻辑上,例如类似于以下内容:

$team->user->role('manager')

Team、User 和 Role 类之间的关系都是多对多的

团队.php

public function users()
    {
        return $this->belongsToMany(User::class, 'team_user', 'team_id', 'user_id')->withTimestamps();
    }

用户.php

    public function teams()
    {
        return $this->belongsToMany(Team::class, 'team_user', 'user_id', 'team_id')->withTimestamps();
    }

    public function roles()
    {
        return $this->belongsToMany(Role::class, 'role_user', 'user_id', 'role_id')->withTimestamps();
    }

角色.php

    public function users()
    {
        return $this->belongsToMany(User::class, 'role_user', 'role_id', 'user_id')->withTimestamps();
    }

管理员/TeamsController.php

    public function index()
    {
        $teams = Team::with('users')->orderBy('location', 'asc')->paginate(10);

        return view('admin.teams.index')->with([
            'teams' => $teams,
        ]);
    }

那么,为了在刀片视图中隔离给定团队的每个成员的角色,我们必须做些什么来加载这样的多个关系?


编辑以显示最终解决方案(来自下面@wschopohl 的强大输入):

在 Team.php 类中:

    public function userWithRole($role)
    {
        return $this->users()->whereHas('roles', function ($query) use ($role) {
            $query->where('name', $role);
        })->with('roles')->get();
    }

index.blade.php

@foreach ($teams as $team)
    <tr>
        <td class="px-4 py-2 border">{{ $team->location }}</td>
        <td class="px-4 py-2 border">
            @foreach ($team->userWithRole('lead') as $user)
                <li style="list-style: none;">{{ $user->name }}</li>
            @endforeach
        </td>
        <td class="px-4 py-2 border">
            @foreach ($team->userWithRole('manager') as $user)
                <li style="list-style: none;">{{ $user->name }}</li>
            @endforeach
        </td>
        <td class="px-4 py-2 border">
            @foreach ($team->userWithRole('somethingelse') as $user)
                <li style="list-style: none;">{{ $user->name }}</li>
            @endforeach
        </td>
    </tr>
@endforeach

【问题讨论】:

    标签: mysql laravel eloquent laravel-blade php-7


    【解决方案1】:

    这实际上比我想象的要复杂。

    我现在能想到的最好的事情是:

    $users = $team->users()->whereHas('roles', function($query) {
        $query->where('name', 'manager');
    })->get();
    

    当然,这很难用在刀片模板中。这就是为什么我会在 Team 模型上使用这样的方法

    public function usersWithRole($role) {
        return $this->users()->whereHas('roles', function($query) use($role) {
            $query->where('name', $role);
        })->with('roles')->get();
    }
    

    所以现在您可以在刀片模板中执行以下操作:

    @foreach($team->usersWithRole('manager') as $user)
    

    【讨论】:

    • 您的假设是正确的(角色表列称为“名称”),但是这条线(我之前已经尝试过很多次)产生:undefined method Illuminate\Database\Eloquent\Relations\BelongsToMany::roles() 似乎 eloquent 没有动通过与用户的团队关系一直到角色。这是近一周来让我陷入死胡同的部分。
    • 尝试更新的答案,对不起,我现在无法测试自己
    • 无需抱歉。我非常感谢您在这里的投入!这似乎有点进步,因为我现在得到:Trying to get property 'name' of non-object
    • 我刚刚注意到您建议末尾的 ->get() 。当我添加它时,它爆发了:Column not found: 1054 Unknown column 'roles.name' in 'where clause' (SQL: select users.*, team_user.team_id` as pivot_team_id, team_user.user_id as pivot_user_id, team_user.pivot_created_at as pivot_created_at @, team_user.updated_at as pivot_updated_at from users inner join team_user on users.id = team_user.user_id 其中team_user.@107 和team_user.@98 987654348@.name = manager and users.deleted_at is null)`它似乎根本没有在探测角色表。
    • 只是一个愚蠢的问题:你所有的关系都在运作,如果你一个一个地查询它们,对吧?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-24
    • 2016-12-19
    • 2018-08-13
    • 1970-01-01
    • 2015-12-01
    • 2014-10-14
    • 1970-01-01
    相关资源
    最近更新 更多