Laravel雄辩 - manyToMany,在sigle pivot table上有多个“角色”

时间:2016-06-16 16:08:13

标签: mysql eloquent laravel-5.2

我有两个模型UserBusinesses

企业可以有很多用户,而企业也可以有很多用户。

例如:

  • John是Business1的管理员。
  • John是Business2的超级拉丁语。
  • Mike是Business1的客户。
  • Mike是Business1的订阅者。

连接这些内容并在以后查询它们的最佳方式是什么。

我构建了一个数据透视表business_user并添加了数据透视列

        $table->boolean('superadmin')->default(false);
        $table->boolean('admin')->default(false);
        $table->boolean('customer')->default(false);
        $table->boolean('subscriber')->default(false);

这是要走的路还是我应该采用不同的方式?对于每种类型的关系,只有其他的东西是不同的数据透视表,但这似乎是一个坏主意。

我会将这些问题视为:

      $user->businesses()->wherePivot('subscriber',true)->get();

我希望我不会错过任何地方的语法,但如果我这样做,请因为其他人而纠正我。

下一步还有Redis

1 个答案:

答案 0 :(得分:1)

你的解决方案运行正常,但是为了以后能够提供更多灵活性(添加更多角色,定义更多与角色的关系,例如权限等),你可以考虑以下内容(注意,这也引入了一点点复杂性,所以考虑一下你是否需要这种灵活性。)

为关系(RoleAssignment)创建专用模型,并为不同角色(Role)创建模型。然后,RoleAssignment与belongsToRoleUser有三个Business关系:

class RoleAssignment extends Model {
    public function role() {
        return $this->belongsTo(Role::class);
    }
    public function user() {
        return $this->belongsTo(User::class);
    }
    public function business() {
        return $this->belongsTo(Business::class);
    }
}

class Role extends Model {
    public function roleAssignments() {
        return $this->hasMany(RoleAssignment::class);
    }
}

class User extends Model {
    public function roleAssignments() {
        return $this->hasMany(RoleAssignment::class);
    }
    public function businesses($roleName = null) {
        return $this->hasManyThrough(Business::class, RoleAssignment::class)->where('name';
    }
}

class Business extends Model {
    public function roleAssignments() {
        return $this->hasMany(RoleAssignment::class);
    }
}

您提供的查询可以写成:

$user->roleAssignments()->whereHas('role', function ($query) {
    return $query->where('name', 'subscriber');
})->with('business')->get()->pluck('business');

为了简化这一点,您可以修改roleAssignments模型上的User关系以接受可选的角色名称:

class User extends Model {
    public function roleAssignments($roleName = null) {
        $relation = $this->hasMany(RoleAssignment::class);
        if ($relation) {
            $relation->whereHas('role', function ($query) {
                return $query->where('name', 'subscriber');
            });
        }
        return $relation;
    }
}

现在您可以编写此查询:

$user->roleAssignments('subscriber')->with('business')->get()->pluck('business');