To achieve the desired functionality of loading user information based on the user's role, you need to dynamically load the relationship based on the role. The issue arises because the UserInfo method is not a standard Eloquent relationship method, and thus, it cannot be used with the load method directly.
Here's a solution that involves dynamically loading the appropriate relationship based on the user's role:
-
Modify the
UserInfomethod to return the relationship name as a string. - Use the returned relationship name to dynamically load the relationship.
Here's how you can do it:
Step 1: Modify the UserInfo Method
Update the UserInfo method to return the relationship name as a string:
public function UserInfo()
{
if ($this->hasRole('manager')) {
return 'managerInfo';
}
if ($this->hasRole('adminer')) {
return 'adminerInfo';
}
if ($this->hasRole('worker')) {
return 'workerInfo';
}
return null;
}
Step 2: Dynamically Load the Relationship in the Controller
In your controller, use the returned relationship name to dynamically load the relationship:
$user = Auth::user();
$relationship = $user->UserInfo();
if ($relationship) {
$user = User::with($relationship, 'Roles')->find($user->id);
} else {
$user = User::with('Roles')->find($user->id);
}
return new InfoFormREResource($user);
Full Example
Here is the complete code for the controller and the modified UserInfo method:
User Model
class User extends Authenticatable
{
public function Roles()
{
return $this->belongsToMany(UserRole::class, 'user_user_roles', 'user_id', 'role_id');
}
public function hasRole($role)
{
if (is_string($role)) {
return $this->Roles->contains('title', $role);
}
}
public function managerInfo()
{
return $this->hasOne(ManagerInfo::class, 'user_id');
}
public function adminerInfo()
{
return $this->hasOne(AdminerInfo::class, 'user_id');
}
public function workerInfo()
{
return $this->hasOne(WorkerInfo::class, 'user_id');
}
public function UserInfo()
{
if ($this->hasRole('manager')) {
return 'managerInfo';
}
if ($this->hasRole('adminer')) {
return 'adminerInfo';
}
if ($this->hasRole('worker')) {
return 'workerInfo';
}
return null;
}
}
Controller
public function showUserInfo()
{
$user = Auth::user();
$relationship = $user->UserInfo();
if ($relationship) {
$user = User::with($relationship, 'Roles')->find($user->id);
} else {
$user = User::with('Roles')->find($user->id);
}
return new InfoFormREResource($user);
}
This approach ensures that the correct relationship is loaded based on the user's role, and it avoids the error related to calling addEagerConstraints on a null value.