Mutli relationships with Eloquent and Laravel - laravel

I have 6 tables:
permissions:
id
permission_name
roles:
id
role_name
user_roles:
id
user_id
role_id
user_permissions:
id
user_id
permission_id
role_permissions:
id
role_id
permission_id
users:
id
username
email
Now I like to add a custom function into my Eloquent model for permissions named getUsersWithPermission().
Now it is possible that user has the permission by the role he has given (user table join on user_roles, join that table on role_permissions and last that table join on permissions.
Or the user has a specific permission set in the user_permissions table (join user_permissions table on user table and join the permissions table on the user_permissions table)
How can I create a Eloquent model function that returns all the users with a specific permission say: "notification.error.process" where that is the permission name
A hasMany doesn't quite do what I want (and I cannot define multi tables in there). I am using Laravel 5.6.

If you defined your many-to-many relations correctly (User-Permission and User-Role-Permission), the following should do the trick:
$permissionName = 'notification.error.process';
$usersWithPermission = User::whereHas('permissions', function($query) use ($permissionName) {
$query->whereName($permissionName);
})->orWhereHas('roles.permissions', function($query) use ($permissionName) {
$query->whereName($permissionName);
})->get();

Try to understand your table structure using this ER diagram.
TO handle this situation, You may create 3 'Eloquent Models'
User
Role
Permission
in every model you may create belongsToMany() relationship to each other models.
one example, On 'User Model'
public function permissions()
{
// need to define any other differences in your tables foreign keys as 2nd, 3rd parameters and so on.
return $this->belongsToMany(Permission::class);
}
Now you need to get all the users 'whom has a role which has the privilege' OR 'whom directly has the privilege.
to do so.
$users = User::whereHas('privileges', function($query) {
$query->where('permission_name', 'notification.error.process');
})->orWhereHas('roles.permissions', function($query) {
$query->where('permission_name', 'notification.error.process');
})->get();
I hope you will get an idea. your code may be slightly different from mine. but this is the concept.

Related

Laravel 9.* belongsToMany

I have DB structure:
user
user_id
office
office_id
property
property_id
office_user
office_user_id
office_id
user_id
office_user_property
office_user_id
property_id
Is there way to acess to Property model from User model via belongsToMany?
What you are looking for is the hasManyThrough
(https://laravel.com/docs/9.x/eloquent-relationships#has-many-through), but it only work for one connection in between, and you have two.
What you could do is define a hasManyThrough relation between user and office_user_property and define a hasOne relation between office_user_property and property
belongsToMany refers to Many To Many. This relationship for your case defines that has many properties, while a property is owened by many users. In a nutshell three database tables can be used to define this relationship. properties table, users table, and user_property table. where the user_property table contains user_id and property_id columns.
In the user model, the relationship can be defined as:
/.../
public funciton properties(){
return $this->belonsToMany('App\Property');
}
To access properties for a user:
$user = App\User::find(1);
foreach ($user->properties as $property) {
//
}
Ref: Laravel 5.2 Docs

I have a laravel project with 2 tables (users and roles). In a roles view, I am trying to display a count of users who are using that specific role

My tables areas follows
roles table (id, roleName, roleDesc)
users table (id, name, role, email)
When adding a new user, I insert a role eg "Admin" into the role column of the user.
My problem is that I want to show the number of users who have that role in a view data table that displays list of roles. Eg would simply be an integer of number of members who share that role, eg 5.
In my roleController, I am fetching records using
$roles = Role::all();
$users = User::all();
I have managed to display a count of users with role "Admin", but this ofcourse just duplicated all down the datatable with eg "1"
$RoleCount = User::where('role', '=', 'Admin')->count();
So, I think I need to use a join or something to replace the 'Admin' above, with current roleName.
I hope that makes sense and I hope someone can help me find a solution. I know this is pretty elementary, but trying to rap my head around joins and having a bit of trouble.
Thanks in advance.
First it will be great to use Relationships (Laravel docs)
With relationships it will be super easy.
Change Users table, so you have there NO the name of role, but ID of role = columns id, name, role_id, email
In Role model add relationship to User, and in User model add relationship to Role:
Model User.php - add method
public function role(){
return $this->belongsTo('App\Role'); //use your correct namespace
}
Model Role.php - add method
public function users(){
return $this->hasMany('App\User'); //use your correct namespace
}
And then just select all roles with count of users:
$roles = Role::withCount('users')->get();
In your view:
#foreach($roles as $role)
{{ $role->roleName }} - {{ $role->users_count }}<br>
#endforeach

Invalid argument supplied for foreach() in laravel when use Eloquent: Relationships

I wanna get the class name of a user via the user ID. When I input the ID of a user so I will wanna get the class name. I have three tables such as users table, classes table, and class_users table. The class_users table is born from two users table and classes table.
A users table has an id, name, email, password.
A classes table has an id, class_code, class_name.
A class_users table has an id, class_id, user_id
And this problem relates to Eloquent Relationships.
Thank you for help.
My Route:
Route::get('/find_classes/{id}','StudentController#find_classes');
My Controller function:
public function find_classes($id)
{
$users = User::find($id);
foreach($users->classes as $class)
{
echo $class->name . '<br';
dd($class);
}
}
My User Model:
public function classes()
{
return $this->belongsTo('App\Classes','class_users','user_id','class_id');
}
Looks like you might have the wrong relationship set up on your User model. You have a one to many set up, but your DB is setup to handle a many to many. I suggest you change your User model relationship:
public function classes()
{
return $this->belongsToMany('App\Classes');
}
Note, you may need to name the FK on that relation, as I see you have class_id on the table, but your actual class is named 'Classes'. Check through your relationships to ensure this is explicit on the FK where it doesn't follow Laravel convention exactly.
With this relationship, your foreach loop should work. It would be a good idea for efficiency, as mare96 noted, to eager load the classes on the $users collection when you query:
$users = User::with('classes')->find($id);

Manage relation using Eloquemt ORM

I am working with Laravel5.4. I have a user table that have column like id,introducer_id,company_id,user_role.
If login user has company_id as 1 than fetch all users who has company_id as 1 and also fetch whose company is not same as login user but user_role is 3.
I need to fetch users as per the above requirement using Eloquent ORM. So how can I write query?
Do this:
User::where('company_id', auth()->user()->company_id)
->orWhere(function($q) {
$q->where('company_id', '<>', auth()->user()->company_id)
->where('user_role', 3);
})
->get();

Laravel eloquent query model with pivot

I have a user model with pivot table role_user.
In my user table I have a field 'active'.
And a user can have multiple roles which are saved in pivot table.
How can I pull all the users where active = 1 and where user has specific role in pivot table?
Try this. This assumes you have an eloquent relationship set up between users and roles. I've only used this type of query in a hasMany / belongsTo relationship, but I think it'll work in your example as well.
$users = User::where('active', 1)->whereHas('roles', function ($query) {
$query->where('role', 'foo');
})->get();
To filter users by role use whereHas() method:
User::whereHas('roles', function($q) use ($role) {
$q->where('role', $role);
})->where('active', 1)->get();

Resources