Sadece bir öneri, yol göstermesi açısından; Şu şekilde yardımcı bir morph-pivot kullanabilirsiniz:
user_has_roles_on_entities
+---------+---------+-----------+-----------------+-------------+
| user_id | role_id | role | roleable_type | roleable_id |
+---------+---------+-----------+-----------------+-------------+
$table->primary(['roleable_id', 'user_id', 'role_id'], 'roleable_primary');
app/Contracts/Roleable/RoleableEntityInterface.php:
interface RoleableInterface
{
public function roles(): MorphToMany;
}
app/Contracts/Roleable/RoleableEntity.php:
trait RoleableEntity
{
public function roles(): MorphToMany
{
return $this->morphToMany(Role::class, 'roleable');
}
}
app/Company.php:
class Company extends Model implements RoleableInterface
{
use RoleableEntity;
}
app/Department.php
class Department extends Model implements RoleableInterface
{
use RoleableEntity;
}
app/User.php:
public function companies(): MorphToMany
{
return $this->morphedByMany(Company::class, 'roleable', 'user_has_roles_on_entities')
->with([
'roles' => function ($q) {
$q->where('user_id', $this->id);
}
])->whereHas('roles', function ($q) {
$q->where('user_id', $this->id);
})->withPivot([
'role'
]);
}
public function departments(): MorphToMany
{
return $this->morphedByMany(Department::class, 'roleable', 'user_has_roles_on_entities')
->with([
'roles' => function ($q) {
$q->where('user_id', $this->id);
}
])->whereHas('roles', function ($q) {
$q->where('user_id', $this->id);
})->withPivot([
'role'
]);
}
public function assignRoleToEntity(RoleableInterface $roleable, Role $role): bool
{
$roleable->roles()->attach($role->id, [
'user_id' => $this->id,
'role' => $role->name
]);
return true;
}
public function hasRoleOnEntity(RoleableInterface $roleable, Role $role): bool
{
return $roleable->roles()
->where('user_id', $this->id)
->where('role_id', $role->id)
->exists();
}
Örneğin;
$adminRole = Role::find(1);
$moderatorRole = Role::find(2);
$company1 = Company::find(5);
$company2 = Company::find(8);
$department = Department::find(16);
$user = User::find(1);
// Kullanıcıyı id'si 5 olan firmada admin yap
$user->assignRoleToEntity($company1, $adminRole);
// Aynı kullanıcıyı id'si 8 olan firmada moderator yap
$user->assignRoleToEntity($company2, $moderatorRole);
// Aynı kullanıcıyı id'si 16 olan departmanda admin yap
$user->assignRoleToEntity($department, $adminRole);
$user->hasRoleOnEntity($company1, $adminRole); // true
$user->hasRoleOnEntity($company2, $moderatorRole); // true
$user->hasRoleOnEntity($department, $adminRole); // true
// Kullanıcının admin olduğu firmalar:
$user->companies()
->where('role_id', $adminRole->id)
->get();
// Departman adminleri
$department->roles()
->where('role_id', $adminRole->id)
->first()
->users;
// vs vs
user_has_roles_on_entities
+---------+---------+-----------+-----------------+-------------+
| user_id | role_id | role | roleable_type | roleable_id |
+---------+---------+-----------+-----------------+-------------+
| 1 | 1 | admin | \App\Company | 5 |
| 1 | 2 | moderator | \App\Company | 8 |
| 1 | 1 | admin | \App\Department | 16 |
+---------+---------+-----------+-----------------+-------------+