Laravel Relationship Union: One Relationship with two tables in a model

Multi tool use
Laravel Relationship Union: One Relationship with two tables in a model
Lets supose this scenery:
We have 3 models -> User, Role and Permission.
Relationships
The final purpose to the User -- Permisson relationships is to override the permission assigned to the user through his role. Just an exception for this User.
I am trying to to something like this:
public function permissions () {
return $this->hasManyThrough('AppPermission', 'AppRole')->merge($this->permissionOverrides);
}
In this case when I try to eager load the model permissions Laravel throws an error 'cause permissions is not detected as a relationships.
In the other hand, what if we change User -- Role relationship to many to many?
Thanks a lot for your knowledge!
EDIT
Role Relationships
public function permissions() {
return $this->belongsToMany('AppPermission')->withTimestamps();
}
Permission relationships
public function roles() {
return $this->belongsToMany('AppRole')->withTimestamps();
}
User relationships
public function roles() {
return $this->belongsToMany('AppRole')->withTimestamps();
}
public function permissionOverrides() {
return $this->belongsToMany('AppPermission')->withTimestamps();
}
The question is how to make the permissions()
relationship merging the role permissions and the user permissions.
permissions()
BETTER EXPLANATION
Due to misunderstanding shown in comments I will try to exlain this better. I had set all the relations between AppUser and AppRole; I also had set the the relationship between AppRole and AppPermission. I can do right now:
$user->role->permissions;
For obtaining this I have configured the pivot table permission_role which stores the relation.
Thats not the case. What I want is to add one more var to the equation. Now I want to have the ability to override the role permissions adding a relationship between AppUser and AppPermission. I have the pivot table permission_user and the relation stablished:
public function permissionsOverride() {
return $this->belongsToMany('AppPermission');
}
The REAL QUESTION is how to obtain all the permissions (both role permissions and overrided permissions in only ONE relationship). I mean merging both relationships.
Why I want to merge relationships? I could do a regular function to do this, but I would want to eager load this relation, Laravel way.
App/Role
App/Permission
That relationship is set in the Role model. The question comes when I try to merge both. I have tried this what you're saying. I will put the relationship stablished on my question.
– LordVermiis
Jul 3 at 8:36
Wouldn't it be best if you create a many to many between app/role and app permission, setup a pivot table called permission_role, then setup another pivot table between user/role called role_user. Since users can belong to roles and roles have permissions. Then you can call something like
$user->roles()->permissions
to get a collection of permissions?– Mike Rodham
Jul 3 at 8:53
$user->roles()->permissions
Here is a pretty good article that explains pivot tables and many to many relationships
– Mike Rodham
Jul 3 at 8:58
stackoverflow.com/q/24184069/5283119 give this a read.
– Mike Rodham
Jul 3 at 10:33
1 Answer
1
You can try like this, ManyToMany relation between User
And Role
, similarly ManyToMany relation between Role
and Permission
.
User
Role
Role
Permission
User Model
public function roles() {
return $this->belongsToMany('AppRole', 'user_role')->withTimestamps();
}
public function permissions() {
return $this->belongsToMany('AppPermission', 'permission_user')->withTimestamps();
}
Role Model
public function users() {
return $this->belongsToMany('AppUser', 'user_role')->withTimestamps();
}
public function permissions() {
return $this->belongsToMany('AppPermission', 'permission_role')->withTimestamps();
}
Fetch Data
$user = User::with('permissions','roles','roles.permissions')->find(1);
$permissions = $user->permissions;
foreach($user->roles as $role){
$permissions->merge($role->permissions); //merger collection
}
dd($permissions->all());
For details you can look https://laravel.com/docs/5.6/eloquent-relationships#many-to-many
And for Collection you can look this https://laravel.com/docs/5.6/collections#method-merge
Thanks a lot, but this is not my question. Please, see my edit, I added a better explanation, for you to get better understanding.
– LordVermiis
Jul 3 at 10:38
@LordVermiis i have updated answer, please try it
– rkj
Jul 3 at 10:48
I would like to do, if possible something like:
$user = User::with('permissions')->all();
– LordVermiis
Jul 3 at 11:50
$user = User::with('permissions')->all();
no, that will only return you user direct permissions not the user role's permissions
– rkj
Jul 3 at 11:51
Thats my original question, how to get the merged collection as a relationship
– LordVermiis
Jul 3 at 13:28
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
For user/role you could setup a pivot table called role_user which many users can have many roles, and many roles can have many users. Since you're getting the permissions not detected as a relationship, have you setup the relationship between
App/Role
andApp/Permission
?– Mike Rodham
Jul 3 at 8:25