6

I'm fairly new to laravel-5 and I love it so far, but I've come out with this doubt while I was working on my project.

In my app I want different user types, let's say Employee, Admin and Freelance. Every type will have ofcourse, different permissions and acces to pages. Since every user type has different data, I created 3 additional tables to my schema, admins, employees and freelancers, and added a field user_type on the users default table, to link it to the new tables, which have a user_type aswell, keeping my default users table small as possible, just login info.

So I started reading around and I came up with polymorphic relationship on eloquent, which apparently is exactly what I wanted. After implementing those models relationships and migrations, I don't know how to keep moving, and how to check if a user is either freelancer, admin or employee and how to give acces to certain page regarding the usertype.

This is how my User Model looks like:

public function userable()
{
    return $this->morphTo();
}

And this is how one the childs look like:

public function user()
{
    return $this->morphOne('User', 'userable');
}

2 Answers 2

7

Since your User model is userable, that means the users table should have the two columns necessary for polymorphic relations: userable_id and userable_type. The userable_type will contain the class name of the owning model (which in your case will be either Admin, Freelancer or Employee). So this will return the user type class:

User::find($id)->userable_type; // Use this to identify the user type

While normalizing the database structure by separating information into different tables and using a polymorphic relation to handle them is very good, I strongly suggest you handle roles in a separate structure. The Entrust package is a very good way of doing that, because it allows for a very robust way of handling user roles and permissions.

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

7 Comments

Does Entrust allow me to have different definitions per role?
Not exactly sure what you mean here. Are you asking if you can use it to handle the polymorphic relation you have set up at this moment?
What I meant is that every user role in my project has different attributes, so the role holds more than just a permision rank. They all share the login information though. In my mind we've got a parent users table with 3 childs, employees, admins and freelancers, disjoint complete relation.
By organizing your user details in different tables you normalized the table structure, which is very good. However that does not mean you have to use the polimorphic relations to handle roles, that's just a architectural choice to efficiently store you user information. Entrust doesn't care about that and it really doesn't need to, it stores it's roles in it's own tables that have a relation only to the main users table. Just define the admin, employee and freelancer roles in Entrust. Even if that feels redundant, I assure you it's not.
The fact that you named the 3 tables employees, admins and freelancers might be throwing you off into thinking that you should use them to handle roles. If you were to name them employee_details, admin_details and freelancer_details it would reflect more accurately what they actually are: tables that store user information not roles.
|
2

You can use the zizaco/entrust package for this. It introduces roles and permissions per role for your users.

In this case, roles are not defined by new models or polymorphic relationships, but simply stored in a roles table. Users and roles are then linked by a pivot table role_user (by default).

Giving access to certain pages becomes really easy:

// Checking for a role
$user->hasRole('admin');

// Checking for a single permission
$user->can('edit-users');

The big advantage of this approach is that you don't have to add new tables, models, migrations et cetera to add new roles and permissions.

In case of "every user type has different data", it really depends on what you mean. If you mean the permissions per role, then this package solves this for you. But if you mean data such as a second address or data that only belongs to certain types of users, I'd consider if it really makes sense to outsource this data to different tables (e.g. if you have a lot of unique data per user type), or if I'd just ignore those extra columns in my users table in cases where they are not needed (maybe make them nullable).

Edit:

No information given on which database is used, but these are cases where i personally like to switch from something like MySQL to a schemaless database like MongoDB. Maybe this is an option for you.

2 Comments

I'll look into that, thanks. I don't think merging my user types in the same table is gonna be correct, since there are many different fields between types and will result into a huge table with a lot of nulls.
True - i forgot to mention that it also depends on how much unique data per user type you have. I edited my answer to take this into account and added a thought about MongoDB ;-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.