RBAC - v1.0.0
Roles
ArtisanPackUI\Rbac\Models\Role is a standard Eloquent model with role-hierarchy support.
Schema
| Field | Type | Notes |
|---|---|---|
name |
string | unique |
slug |
string | unique; auto-derived from name via Str::slug() if not provided |
description |
string | null | |
parent_id |
int | null | foreign key to roles.id; set null on parent delete |
timestamps |
datetime |
Relationships
permissions()→BelongsToMany Permissionusers()→BelongsToManyagainstconfig('auth.providers.users.model')parent()→BelongsTo Rolechildren()→HasMany Role
Creating
use ArtisanPackUI\Rbac\Models\Role;
$editor = Role::create([
'name' => 'Editor',
// 'slug' is auto-derived to 'editor'
'description' => 'Can publish and edit content',
]);
Supplying an explicit slug overrides the auto-derivation:
Role::create(['name' => 'Editor', 'slug' => 'content-editor']);
Hierarchy
Set parent_id to nest roles. Permissions resolve recursively up the chain via HasPermissions::hasPermissionTo().
$admin = Role::create(['name' => 'admin']);
$editor = Role::create(['name' => 'editor', 'parent_id' => $admin->id]);
$editor->parent; // admin Role
$admin->children; // collection containing editor
A user with the editor role will resolve to the union of editor's direct permissions plus all of admin's permissions (and grandparents, recursively).
When a role is deleted, its children have parent_id set to null rather than being cascaded.
Slug lookup
Role::findBySlug('editor'); // ?Role
Role::whereSlug('editor')->first(); // ?Role (via scope)
hasRole('editor') and assignRole('editor') (from the HasRoles trait) both match against either name or slug.
Attaching permissions
$editor->permissions()->attach($publishPermission);
$editor->permissions()->sync([$publish->id, $draft->id]);
$editor->permissions()->detach($draftPermission);
Standard Eloquent BelongsToMany — no package-specific behaviour. Sync clears the permission cache automatically via the observer (see Caching).
Cascading deletes
Role::delete() detaches the role's permissions and nulls parent_id on its children before the row is removed. This avoids dangling pivot rows and avoids orphaned children.
Collision detection
Role::save() will throw if the supplied name or slug collides with another row's value in the opposite column (e.g. saving name: 'editor' when an existing row has slug: 'editor'). This prevents subtle lookup ambiguity in slug-based helpers.