【问题标题】:Should I use BelongsToMany, hasManyThrough or join?我应该使用 BelongsToMany、hasManyThrough 还是加入?
【发布时间】:2021-04-30 13:59:26
【问题描述】:

这是我想要生成的(请注意,一个成员具有固定的角色,并且可以在同一个项目中出现在多个角色下):

Project 1
    Gardeners
        John Doe
        Lisa Smith
    Janitors
        Eric Black
        John Doe
    Pool keepers
        Bella Johnson

Project 2
    Gardeners
        Lisa Smith
    Janitors
        Bella Johnson
        John Doe
        Lisa Smith

数据库:

项目

  • id
  • title

成员

  • id
  • name

角色

  • id
  • name

member_role

  • id
  • member_id
  • role_id

member_role_project

  • id
  • member_role_id
  • project_id

还有比下面更好的方法吗?

class Project extends Model
{
    use HasFactory;

    public function memberRoles(): BelongsToMany
    {
        return $this->belongsToMany(MemberRole::class, 'member_role_project', 'project_id', 'member_role_id');
    }
    public function members(): BelongsToMany
    {
        return $this->memberRoles()->with('Member', 'Role');
    }
}

$projects = Project::with('members')->get();
$data = collect([]);

foreach ($projects as $project) {
    $roles = collect([]);
    foreach ($project->members as $role) {
        if (!$roles->contains('id', $role->Role->id)) {
            $roles->push($role->Role);
        }
    }
    $item = [
        'project' => $project,
        'roles' => $roles->map(function ($role) use ($project) {
            return [
                'title' => $role->name,
                'members' => collect($project->members->where('role_id', $role->id))->sortBy('member.name')
            ];
        })
    ];

    $data->push($item);
}

似乎必须有比这更简单的方法?引用另一个数据透视表的数据透视表让我很头疼,但希望 Laravel 有一个魔术! :)

【问题讨论】:

    标签: php laravel laravel-8


    【解决方案1】:

    您可以使用一个表来完成此操作,而不是使用两个数据透视表。假设我们将此表命名为permissions。结构看起来有点像:

    permissions: id, member_id, role_id, project_id
    

    这是一种三向多对多关系,我经常为此使用单独的模型。

    成员、角色、项目:

    function permissions() {
       return $this->hasMany(Permission::class);
    }
    

    权限:

    function member() {
       return $this->belongsTo(Member::class);
    }
    
    function role() {
       return $this->belongsTo(Role::class);
    }
    
    function project() {
       return $this->belongsTo(Project::class);
    }
    

    那么你可以这样查询:

    $user->permissions()->where('project_id', $projectId)->first()->role();
    
    foreach ($project->permissions as $permission) {
        $role = $permission->role;
        $member = $permission->member;
    }
    

    【讨论】:

    • 谢谢!我实际上是从尝试找出使用 2 个枢轴或 3 路表是否更好:stackoverflow.com/questions/67326374/…
    • 当我上次尝试 3 种方式时,我遇到了无法在我的播种机上使用附加功能等问题,Laravel 中是否也有内置解决方案可以解决 3 个外键问题那还是我当时输入自定义查询土地?在您的示例中,PermissionModelPivot 的扩展?再次感谢!
    • 最后一件事,是否可以展示一个示例,说明您将如何查询以获取顶部两个项目的示例列表的数据?会很有帮助!我对此很陌生。
    • 我还想补充一点,member_role 表用于跟踪成员的角色,这就是为什么我试图弄清楚 3 路表是否是多余的,但我猜两种解决方案各有利弊。
    • 恐怕 Laravel 没有内置的解决方案。这就是为什么我们必须满足于骇人听闻的解决方案。但我发现这是处理这种情况的最佳方法。是的,Permission 应该扩展 Model
    猜你喜欢
    • 2021-12-29
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 2018-03-08
    • 2018-09-05
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多