How to make user, and roles relationship in Laravel 5
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Relationships: How to Link Users and Roles in Laravel Eloquent
As a senior developer working with the Laravel ecosystem, managing relationships between models—especially one-to-many and many-to-one associations—is fundamental. When structuring data for authentication and authorization systems, linking users to their respective roles is a common requirement. The issue you are encountering stems from how Eloquent handles lazy loading and relationship access.
This post will walk you through setting up the correct relationships in Laravel 5 (and modern versions) to seamlessly retrieve role details from a user object, solving the "Trying to get property of non-object" error you faced.
Understanding the Many-to-One Relationship
Your schema clearly defines a many-to-one relationship: many users can belong to one role, but each user belongs to only one role.
Schema Review:
Usertable hasrole_idreferencingroles.id.Rolestable holds the role details (name, access).
To manage this efficiently using Eloquent, we define two key relationships:
- User to Role (Belongs To): A User belongs to one Role.
- Role to Users (Has Many): A Role can have many Users.
Implementing the Eloquent Relationships
The structure you provided for your models is almost entirely correct, but we need to ensure the setup is robust and correctly defined within the context of a Laravel application.
The User Model Setup
In your User model, defining the relationship to the Role model is crucial:
// app/Models/User.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class User extends Model
{
/**
* Define the relationship to the Role model.
*/
public function role(): BelongsTo
{
// This tells Eloquent that a User belongs to a single Role.
return $this->belongsTo(Role::class);
}
// ... other model code
}
The Role Model Setup
Similarly, the Role model needs a relationship to find all associated users:
// app/Models/Role.php
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class Role extends Model
{
/**
* Define the relationship to the User model.
*/
public function users(): HasMany
{
// This tells Eloquent that a Role has many Users.
return $this->hasMany(User::class);
}
// ... other model code
}
Diagnosing and Solving the Error
The error "Trying to get property of non-object" usually occurs when you attempt to access a relationship that hasn't been loaded or defined correctly, especially if you are dealing with nested calls. When using belongsTo, Eloquent automatically loads the related model instance.
Let's re-examine how you tried to access the data:
$user = User::find(1);
// Attempting this caused the error:
// $details = [
// 'name' => $user->first_name,
// 'role' => $user->role->role_name // <-- Error occurs here if 'role' is null or not loaded correctly.
// ];
If your role_id in the users table is populated, accessing $user->role should return a Role model object. The error suggests one of two things: either the role_id is missing for that user (i.e., role_id is NULL), or there is an issue with how you are resolving the relationship during access.
The Correct Way to Access Nested Data
The most robust way to handle this in Laravel is to ensure you load the necessary data efficiently, especially when dealing with collections of users. We use Eager Loading to prevent N+1 query problems.
To fetch a user and their associated role in a single, optimized query, use the with() method:
// Fetch User 1 along with their related Role data
$user = User::with('role')->find(1);
if ($user) {
// Now access the relationship safely. $user->role is the Role model instance.
$roleName = $user->role->role_name;
$userName = $user->first_name;
$details = [
'name' => $userName,
'role' => $roleName
];
// Output: ['name' => 'John', 'role' => 'Admin']
} else {
// Handle case where user is not found
}
By using with('role'), Eloquent performs a single JOIN query behind the scenes, which is far more efficient than running separate queries for each user and then attempting to load the relationship later. This practice is central to building high-performance applications, aligning with best practices found on https://laravelcompany.com.
Conclusion
Establishing clear, bidirectional relationships between your models is the backbone of any well-structured Laravel application. By correctly defining belongsTo and hasMany relationships, you empower Eloquent to handle complex database joins for you. Always ensure your foreign keys are populated in the database, and leverage eager loading techniques like with() when retrieving related data to maintain performance. Mastering these concepts will make managing user roles and permissions straightforward and scalable.