Laravel belongsToMany get one record - laravel

I have three tables as below:
users
id|name|username|password
roles
id|name
users_roles
id|user_id|role_id
These tables communicate via belongsToMany.
Table users_roles has many records. The user can change his role, but I have to store every change.
id
user_id
role_id
1
2
2
1
3
2
1
2
3
1st. How can I get the last and single role_id with the user?
$users = User::with('roles')->get();
Now I'm getting user(2) with two roles, but I need user(2) with single and last role(3).
2nd. How I can access roles->name on the blade?
#foreach($users as $user)
{{ $user->name }} <<< normal
{{ $user->roles['name']}} <<I'm getting error here

roles will be a collection so you could just use the last() method and have something like:
$user->roles->last()->name;
Alternatively, if you can update to Laravel >= 8.42, you could use the Has one of many relationship.
Create a new relationship in your User model:
public function latestRole()
{
return $this->hasOne(Role::class)->latestOfMany();
}
Then you would load the role with latestRole:
$users = User::with('latestRole')->get();
This way you can access the relationship directly:
#foreach($users as $user)
{{ $user->latestRole->name }}

You can use whereHas
$users = User::with('roles')->whereHas('roles', function ($q) {
$q->latest();
})->get();

Related

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

How to access other fields on a three way pivot in Laravel?

Here's what my architecture looks like:
The idea is that a user have a role on a given group. Of course, the user belongs to many groups, and a user can have multiple roles (in different groups)
I'm trying to get all the groups a user belongs to.
Please forgive me for not using the convention to name the pivot table as groups_roles_users, I decided this way for readability.
So, in the User model I say:
public function groups() {
return $this->belongsToMany('\App\Group', 'roles_in_groups');
}
In a view I do:
#foreach ($user->groups as $group)
{{ $group->name }}
#endforeach
works perfectly.
Now I want to access the roles table. I want to print something like: In {{ $group->name }} you're a {{ $group->role->name }}, obviously, It doesn't work like that.
If I use the pivot property, it will give me only the user_id and group_id, not even the role_id to search with an static method.
SO, how can I accomplish that?
I'm using Laravel 5.7
Maybe try:
public function roles() {
return $this->belongsToMany('\App\Role', 'roles_in_groups');
}
$user = \User::with(['roles','groups'])->first();
$role_name = $user->role->name
$group_name = $user->group->name
https://laravel.com/docs/5.7/eloquent-relationships#eager-loading

Laravel - Get users name from ID

I have a Laravel 5.6 app that is logging various information into a database table, I am then displaying this data in a HTML view. I am calling this view like this...
$logs = Log::all();
return view('logreport.index')->with('logs', $logs);
The table only contains the user ID, is there a way to get the users first name and last name for the users table? Or do I need to set a relationship up?
if the log table contain the user_id and you want to get user name you can get the user name through relation as the following:
in log model add the following method:
public function user(){
return $this->belongsTo('App\User','user_id','id');
}
and then you can access the user information in view file such as firstname as the following
#foreach($logs as $log)
<h1>{{$log->user->first_name .' '.$log->user->last_name }}</h1>
#endforeach
You don't need to set a relationship. Just use eloquent.
$users = User::whereIn('id', array(...))->get();
Or with query builder
$users = DB::table('users')->whereIn('id', array(...))->get();
Replace the dots by the values of your IDs
You can use Eloquent relationship as answered by Ali or you can use "Joins" with your result as:
$logs = Log::join('users', 'users.id', '=', 'logs.user_id')->get();
return view('logreport.index')->with('logs', $logs);
and then access the result as:
<h1>{{ $log->first_name .' '. $log->last_name }}</h1>

How do i query the database to grab each user post and count the number of post from the user?

I am trying to make a datatable, but I am having trouble querying the database. What I want to do is select one instance of each user on the datatable and I want to grab a count of all the products created by that user.
Products Table
id user_id title
1 2 tv
2 2 car
3 2 book
4 3 glasses
So user(2) has 3 products
So user(3) has 1 products
Here is the code I been working on
$users = DB::table('users')
->join('products', 'users.id', '=', 'products.user_id')
->select('users.*', 'products.id', 'url')
->groupBy('products.id', 'url')
->get();
You need to select the user details, together with a count of the products, grouped by the user id, as follows:
$users = DB::table('users')
->selectRaw('users.*, COUNT(products.id) AS products')
->join('products', 'users.id', '=', 'products.user_id')
->groupBy('users.id')
->get();
You can do this really simply with eloquent
Say you have your User model and Product model.
In your database structure, for your products table, you need to include a column called user_id as an integer data type.
Then You declare this relationship on the user model
public function products()
{
return $this->hasMany(Product::class);
}
then the inverse of the relation on the product's model
public function user()
{
return $this->belongsTo(User::class);
}
Now you can simply do the following
//This returns all users with products (eager loading pointes out by fubar)
$users = User::with('products')->get();
//Now you could pass $users to your view and loop through like so
#foreach($users as $user)
<li>{{ $user->name }} has {{ $user->products->count() }} </li>
#endforeach
for a specific user, you can simply
$user = User::find($id);
$userProductCount = $user->products->count();
eloquent really does make everything so clean and beautiful

Laravel Many To Many Method Issue

I have a many to many relationship between the models User & Notification.
User Model:
public function notifications()
{
return $this->belongsToMany('Yeayurdev\Models\Notification', 'notifications_user', 'user_id', 'notification_id')
->withPivot('notifier');
}
Notification Model:
public function user()
{
return $this->belongsToMany('Yeayurdev\Models\User', 'notifications_user', 'notification_id', 'user_id');
}
Pivot Table:
ID USER_ID NOTIFICATION_ID
1 2 1
In my view, I retrieve a list of all notifications for a user like so.
#foreach (Auth::user()->notifications as $notification)
{{ $notification->user->username }}
#endforeach
The problem is that when I try to get the username of the user with that notifications, I get the error Undefined property: Illuminate\Database\Eloquent\Collection::$username. "Username" is the column on my users table which is just a string. I don't see where I'm going wrong because if I just do "$notificatin->user" it gives me the collection.
Thanks!
As you said, the relationship is many-to-many, so $notification->user in your case is returning a collection of User models, NOT a single user. If you need only a first user then just do
{{ $notification->user()->first()->username }}
If you need to print out all users for every notification, then you will need a loop here to go through all users.
#foreach (Auth::user()->notifications as $notification)
#foreach($notification->user as $notificationUser)
{{ $notificationUser->username }}
#endforeach
#endforeach
I would recommend renaming user() relationship to users() to avoid confusion in the future.

Resources