Skip to content

Instantly share code, notes, and snippets.

@alejoasotelo
Last active June 11, 2024 22:02
Show Gist options
  • Save alejoasotelo/14ed9326168503330adb808e65e8c592 to your computer and use it in GitHub Desktop.
Save alejoasotelo/14ed9326168503330adb808e65e8c592 to your computer and use it in GitHub Desktop.
Fix muchas consultas sql para laravel nova (silvanite/novatoolpermissions:1.1 instala silvanite/brandenburg:1.0 con el error).

La librería silvanite/novatoolpermissions:1.1 usa silvanite/brandenburg:1.0. La versión 1.0.7 de silvanite/brandenburg trae la mejora que optimiza las consultas a la base de datos. Con solo cambiar 2 archivos de la 1.0 se corrige el problema: src/Traits/HasRoles.php y src/Role.php

Links del commit con el fix:

Además de esta corrección agregué una cache en tiempo de ejecución para evitar duplicaciones de consultas a la base de datos.

<?php
namespace Silvanite\Brandenburg\Traits;
use Silvanite\Brandenburg\Role;
trait HasRoles
{
/**
* Get all Roles given to this user
*
* @return void
*/
public function roles()
{
return $this->belongsToMany(Role::class)->with('getPermissions');
}
/**
* Scope a query to eager load `roles` relationship
* to reduce database queries
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeWithRoles($query)
{
return $query->with('roles');
}
/**
* Determine if any of the assigned roles to this user
* have a specific permission
*
* @param string $permission
* @return boolean
*/
public function hasRoleWithPermission($permission)
{
return $this->roles->contains(function ($role) use ($permission) {
return $role->getPermissions->contains('permission_slug', $permission);
});
}
/**
* Assign a role to this user
*
* @param string|Role $role
* @return boolean
*/
public function assignRole($role)
{
if (is_string($role)) {
return $this->roles()->attach(Role::where('slug', $role)->first());
}
return $this->roles()->attach($role);
}
/**
* Remove a role from this user
*
* @param string|Role $role
* @return boolean
*/
public function removeRole($role)
{
if (is_string($role)) {
return $this->roles()->detach(Role::where('slug', $role)->first());
}
return $this->roles()->detach($role);
}
/**
* Reassign roles from an id or an array of role Ids
*
* @param int|array $roles
* @return void
*/
public function setRolesById($roles)
{
$roles = is_array($roles)? $roles : [$roles];
return $this->roles()->sync($roles);
}
}
<?php
namespace Silvanite\Brandenburg;
use Silvanite\Brandenburg\Policy;
use Illuminate\Support\Facades\Gate;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
class Role extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'slug',
'name',
'permissions',
];
/**
* The attributes which should be extended to the model
*
* @var array
*/
protected $appends = [
'permissions',
];
/**
* Cast attributes to their correct types
*
* @var array
*/
protected $casts = [
'permissions' => 'array',
];
/**
* Get all users which are assigned a specific role
*
* @return Illuminate\Support\Collection
*/
public function users()
{
return $this->belongsToMany(config('brandenburg.userModel'));
}
/**
* Returns all Permissions for this Role
*
* @return Illuminate\Support\Collection
*/
public function getPermissions()
{
return $this->hasMany(Permission::class);
}
/**
* Replace all existing permissions with a new set of permissions
*
* @param array $permissions
* @return void
*/
public function setPermissions(array $permissions)
{
if (!$this->id) {
$this->save();
}
$this->revokeAll();
collect($permissions)->map(function ($permission) {
$this->grant($permission);
});
}
/**
* Check if a user has a given permission
*
* @param string $permission
* @return boolean
*/
public function hasPermission($permission)
{
return $this->getPermissions->contains('permission_slug', $permission);
}
/**
* Give Permission to a Role
*
* @param string $permission
* @return boolean
*/
public function grant($permission)
{
if ($this->hasPermission($permission)) {
return true;
}
if (!array_key_exists($permission, Gate::abilities())) {
abort(403, 'Unknown permission');
}
return Permission::create([
'role_id' => $this->id,
'permission_slug' => $permission,
]);
return false;
}
/**
* Revokes a Permission from a Role
*
* @param string $permission
* @return boolean
*/
public function revoke($permission)
{
if (is_string($permission)) {
return Permission::findOrFail($permission)->delete();
}
return false;
}
/**
* Remove all permissions from this Role
*
* @return void
*/
public function revokeAll()
{
return $this->getPermissions()->delete();
}
/**
* Get a list of permissions
*
* @return array
*/
public function getPermissionsAttribute()
{
$cacheKey = 'getPermissionsAttribute-'.$this->id;
$ttlSeconds = 60;
$result = Cache::remember($cacheKey, $ttlSeconds, function () {
return Permission::where('role_id', $this->id)->get()->pluck('permission_slug')->toArray();;
});
return $result;
}
/**
* Replace all existing permissions with a new set of permissions
*
* @param array $permissions
* @return void
*/
public function setPermissionsAttribute(array $permissions)
{
if (!$this->id) {
$this->save();
}
$this->revokeAll();
collect($permissions)->map(function ($permission) {
if (!in_array($permission, Policy::all())) {
return;
}
$this->grant($permission);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment