@mstnorris The question is, what you need. Common practice is assigning roles to the users. Either User belongsTo Role or User belongsToMany Role (speaking relations), depending on whether a user can have just one or more roles.
Advice: How to model different user types?
I need to model different types of users and want some advice as to how I should proceed.
I have different users for example students, teachers, and other staff members, how should I go about implementing this?
Do I just assign the different users various roles? Or do I use separate models?
I have the default User model and then three roles Student, Teachers, and other Staff. A User can belong to any (multiple) of the three roles. Each of the roles will have with it different permissions. Is this the best way to do it or should Students, Teachers, and Staff extend the User model?
@mstnorris I would say that if it is only about permissions, then there is no reason for polymorphism (extending classes). Just create m-m relationships and determine given user's permissions based on role's permissions. You can extend it a bit by overriding the permissions on user's level.
@JarekTkaczyk it isn't just about permissions as Students can take different Modules (which in turn belong to various Courses). Teachers teach various Courses, Modules, and Classes.
As such, I can't see how the default User model itself can have-many or belong-to-many modules.
What are the best practices for proceeding?
@mstnorris Yes, then I suggest polymorphism indeed.
So, put everything that is common to every role in the User model and specific things in each model. like below:
// abstract class User
// probably everything concerning login etc
// Teacher extends User
public function courses()
{
return $this->hasMany('Course');
}
// Student extends User
public function courses()
{
return $this->belongsToMany('Course');
}
You get the idea.
One thing to have in mind - if you make User abstract then you need to adjust eg. Auth funcitonality, but on the other hand there is less chance that you mess something with the roles.
if the three type of users are stored in the same users table, a cool trick is to use global scopes on your models.
<?php namespace App\Scopes;
use Illuminate\Database\Eloquent\ScopeInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
class TeacherScope implements ScopeInterface{
public function apply(Builder $builder, Model $model)
{
$builder->where('type', '=', 'teacher');
}
public function remove(Builder $builder, Model $model){}
}
<?php namespace App;
use App\Scopes\TeacherScope;
class Teacher extends User{
public static function boot()
{
parent::boot();
static::addGlobalScope(new TeacherScope);
}
}
This way Teacher::all() etc... returns only the teachers no need for additional where conditions everywhere.
@JarekTkaczyk thank you. What would the benefits / disadvantages (or is this not even related) to using Interfaces?
@pmall, that's also great. I've only just read up on scopes and that sounds great!
What would the benefits / disadvantages (or is this not even related) to using Interfaces?
You can have an UserInterface defining every public method a user should implement. For example if you have a method SomeMethod and your three kind of user should return something different (so you cant put it in the parent user class), you can ensure all the user classes implement it. This way if you pass an user instance to any method you are sure you can use SomeMethod on this instance.
It is more a matter of structure than functionnality.
@pmall thank you, that makes sense. I will give it a go!
@mstnorris interface and abstract User class is pretty much the same in this case. You can define these methods either in the interface or in the User making them abstract. Of course global scopes are the way to go for the queries, just like @pmall already said.
I'll do a Laracasts lesson on this stuff. Would make for a good topic.
Any updates?
@JeffreyWay Is this already recorded, if so could you please provide the lesson link?
@JeffreyWay any news on this lesson. I've fleshed out more of my app but I'm back at the same point where this is now becoming an issue and would like a little help. Thanks
@JarekTkaczyk when you say I would have to adjust the Auth functionality, would you mind providing an example. Thank you
Has the lesson about this topic come out already or not??
Also,whould you mind telling me how you ended up integrating this feature?
hi @JeffreyWay has lesson been published? Hope to see it soon! Thanks
Please or to participate in this conversation.