0
votes

I am trying to make a blog like app using Laravel and Vue but got stuck at a point. While developing the admin panel, I wanted a "Assign role" feature there where the admin can assign a user with particular role like "Admin, Moderator or Author" For that, I defined a relationship in User model

public function role() {
    return $this->hasOne(Role::class);
}

Now in Vue, I want to display a table with all user names with their Roles besides them. For that, I sent a request to laravel server to fetch all data from Users table, the users table have the fields below

id , name, role_id , email , password, created_at, updated_at

I have a relationship defined in the Role model aswell

public function Users() {
    return $this->hasMany(User::class);
}

Now when I fetch all users, I do

$users = User::all();
return $users;

How can I get the Role name inside my table, from the data i sent above. Right now, I am only getting the role_id that is 1,2 or 3 but I want the names of the roles.

Thanks in advance

3
I said this comment elsewhere but i'm not sure you've done it: public function role() { return $this->belongsTo(Role::class); } You used the wrong relationship type - TKoL
@TKoL, why should I not use hasOne here? Doesnt it make more sense that User "HAS ONE" role ? - Steal1702
No the thing is there is one to many relation bw Role and User. So each user belongsTo a particular role, and a role has many users. hasOne is used for one to one relationship. - Aashish gaba
'belongsTo' vs 'hasOne' depends on which one has a column for the id of the other one. 'belongsTo' when the model you're in, Users, contains a column for the id of the model you're relating to, Roles. 'hasOne' if the Roles table had a column for user_id, which you can see in the error message - TKoL

3 Answers

2
votes

You need to change your relation.

User Model

public function role(){
   return $this->belongsTo(App\Role::class, 'role_id', 'id')
}

You can use the role relation and get the name from there.

// Eager load the relation
$users = User::with('role')->get();
return $users;

In your html.

$user->role->name;
2
votes

I think one of your relationships is wrong for starters, should be

public function role() {
    return $this->belongsTo(Role::class);
}

To minimize database queries do this:

$users = User::with('role)->get();

Now you can do something like

$users->toJson()

if you want to pass all the data to a javascript.

Or you can do

@foreach($users as $user)
    {{ $user->role->name }}
@endforeach

The important thing is that the with statement loads all the relationships in advance and so only one database query is executed.

-1
votes
$users = User::all();
foreach($users as $user) {
    $user->role;
}
return $users;

Believe it or not, that's all you need to do to populate the relationship inside any generated JSON. You just have to call the "magic method"