Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

goatshark's avatar

User Roles Chaos

Hello everyone,

I've fallen down the rabbit whole and am really hoping for some sanity checking from whoever has opinions on this.

I'm using Entrust to implement user roles. I am not currently using the permissions piece, just three different roles. Thinking I was cool, I added an event to postLogin that set's a Session variable called 'myRole' to the appropriate Role for that user (either 'customer', 'tech', or 'admin').

I see so many different ways of handling this. I'm trying not to make a complete mess of this project. Options, as I see them right now:

  1. Create separate routes for each role, like "Route::get('customers/tickets')..." "Route::get('techs/tickets')...". Have those point to individual controllers, like "CustomersController", "TechsController". Have those return separate views so I end up with views directories like "customers", "techs", etc.

  2. Keep sensible, "normal" routes like "Route::resource('tickets', 'TicketsController'); and let my controller disstinguish between roles, fill variable names that are the same for each role so that I can pass it all on to a single view structure.

Or a mix of those. I am using model scopes to get the appropriate data from the database which seems to be adding an added layer of organization complexity.

Right now I kind of have a mix of all this going on and things are getting a little out of control, disjointed, and definitely less and less scalable as I go. Just looking for opinions on good ways to handle user roles without making a complete mess out of things.

How do you approach this? What has worked well for you? What has been a disaster?

Thanks in advance for any thoughts!!!!

0 likes
7 replies
davorminchorov's avatar

Have you considered using middleware to restrict access based on roles? You can use middleware to check for the roles of the users, and let them see the page if they have the right role. If not, just redirect them back.

Option #1 seems like a chaos to me, so I would never use it.

NathanIsaac's avatar

I would probably keep things simple and use your second method.

// Routes
Route::resource('tickets', 'TicketsController');

// TicketsController
$role = Auth::user()->role;
$tickets = Tickets::getByRole($role);

return view('tickets.index', compact('tickets'));

I would do something a little different if you wanted to have managers see all types of tickets. Something like this.

// Routes
Route::resource('manage/tickets/{$role}', 'Manage\TicketsController');

// Controller
if (is_null($role))
    $role = 'customers';

$tickets = Tickets::getByRole($role);

return view('manage.tickets.index', compact('tickets'));
goatshark's avatar

Ruffles, dead on - I have middleware that's checking roles and restricting as necessary. My confusion started there - at what to do about controllers and views that are mostly the same with a little bit different behavior based on role. Also, I agree that #1 is/was ridiculous and I might as well create three different sites if I go in that direction - which is also ridiculous. I appreciate your input here.

nisaac2fly - Thanks for your input. I'm definitely going to stick with sensible, non-role-specific routes as a rule. I'll also hold on tight to the single view rule - and then coerce my controllers+model scopes into adhering to those rules. Seems the most sensible. Some feedback I got on the #slack channels was to use an Interface for this. I'm reading up on that as I've never implemented one before. So, still up in the air on precisely how I'm going to execute this, but I really appreciate the sanity check! Thank you.

NathanIsaac's avatar

@goatshark I am kind of curious what you mean by the "single view rule". Would you happen to have an example?

davorminchorov's avatar

I believe he's talking about one view where he'll let the user see content based on his role.

Pass an object to every view (maybe a view composer will be helpful here) and show content based on a role. Similar to how you show content for authenticated users with the Auth facade.

goatshark's avatar

Maybe "single view" was a poor choice of words. I have my layout for what a list of tickets looks like - regardless of whether or not you're looking at "open" tickets, "closed" tickets, or even regardless of what your role is. So what I've got going now is that my TicketsController is, for any method that's going to return a view with a list of messages, producing an array/collection(?) called $tickets. The "single view" I'm talking about (while I just make up terms, sorry!) just iterates through ($tickets as $ticket)..... so that it never has to change. I just fill $tickets in my controller with whatever the appropriate data is.

Does that make sense?

Please or to participate in this conversation.