1

I am using my own implementation for user roles and permissions in laravel how to cache all the permissions and roles on user login and also to refresh the cache when new record is added. My tables are users ,roles, permissions,permission_role,permission_user,role_user. This is my table structure

i have created on of the provider and added this code to boot method

Permission::get()->map(function ($permission) { Gate::define($permission->name, function ($user) use ($permission) { return $user->hasPermission($permission); }); }); 

it is working fine but it is running the query each time which gets slowing down my application is there any way to cache all the permissions

here is my PermissionServiceProvider class

<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; use Illuminate\Support\Facades\Gate; use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Blade; use App\Models\Permission; class PermissionServiceProvider extends ServiceProvider { /** * Bootstrap services. * * @return void */ public function boot() { if (Schema::hasTable('permissions')) { Permission::get()->map(function ($permission) { Gate::define($permission->name, function ($user) use ($permission) { return $user->hasPermission($permission); }); }); } Blade::directive('role', function ($role) { return "<?php if(Auth::user()->hasRole({$role})): ?>"; }); Blade::directive('endrole', function ($role) { return "<?php endif; ?>"; }); } /** * Register services. * * @return void */ public function register() { // } } 

and finally inside the user model

public function hasPermission($permission) { return $this->hasPermissionThroughRole($permission) || (bool) $this->permissions->where('name',$permission->name)->count(); } public function hasPermissionThroughRole($permission) { foreach($permission->roles as $role) { if($this->roles->contains($role)) { return true; } } return false; } 

and also here is my bit bucket repo

https://[email protected]/manojkiran/userrolesandpermissions.git

i have tried the method of @emtiaz-zahid https://stackoverflow.com/a/53511803/8487424 its working fine to cache all the permisisons in permissions table but is there any way to cahe all the permisisons and also the permissions to specifc user and role of the currently logged in user

3
  • 1
    how to cache all the permissions and roles on user login and also to refresh the cache when new record is added. there are few approaches: 1) just cache it in session or cookie, 2) cache it using laravel cache feature and purge the cache whenever update is done Commented Nov 28, 2018 at 1:06
  • 1
    First elaborate your question with some code if available. Commented Nov 28, 2018 at 1:09
  • here is my complete code Click here Commented Dec 11, 2018 at 6:49

3 Answers 3

0

You could use Laravel model cache like shown in the following link:

https://laravel-news.com/laravel-model-caching

I would create a method for getting and caching the current users roles and permissions.

You can read more about Caching here:

https://laravel.com/docs/5.7/cache

I hope this helps

Update

Try something like this

if (Schema::hasTable('permissions') ) { $userId = Auth::user()->id return Cache::remember($this->cacheKey() . $userId . ':permissions', 60, function() use ($userId) { return Permission::where('user_id', $userId)->get(); } } 

Then you just need to update your hasPermission() method to check the cache.

Also try to avoid map() as php takes a lot longer than sql

Sign up to request clarification or add additional context in comments.

3 Comments

I have updated my answer with example of the code to use!
i have tried it but i am getting error see here
You have forgotten the ; after setting the userId
0

You can store your cache in service provider. I just sharing my method

$permissions = Cache::rememberForever('permissions', function () { return Permission::get(); }); 

this will remember permissions with key name permissions forever until you change it

you can also remember this with specific time

 $permissions = Cache::remember('permissions', 3600, function () { return Permission::get(); }); 

I placed it in app service provider so that every time on app load it check if permissions found in cache then don't run the query and if not found then take it from DB

so your script could be like this after the cache part:

$permissions->map(function ($permission) { Gate::define($permission->name, function ($user) use ($permission) { return $user->hasPermission($permission); }); }); 

find more on Laravel Documentation

5 Comments

Hi Emitaz. That will get all permission but not the permissions for the current user
I just shared the concept of store data in cache and then use it later, you can check if the current user permissions exists in $permissions array or not.
now i have tried it it is caching all the permission available in the permissions table
but is there any way to cache all the permissions and also the permission to specific user or roles who is currently loggging in
currently logged user data can be found in Auth::user() , and its all data are stored in session, so every time when you need to get any data from user table it does not execute another query.
0

finally I found the solution. Artisan cache clear command is not working well. Try to remove the cache on this folder. storage/framework/cache/data

This should work for sure. Good luck

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.