Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

murilo's avatar
Level 10

load info of user depends on type of the user model

hello , I am trying to get info user depends of type of user with load , something like this

controller

$user = User::find(Auth::user()->id)->load('UserInfo', 'Roles');
 return  new InfoFormREResource($user);

user model -

  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 $this->managerInfo();
        }

        if($this->hasRole('adminer)){
            return $this->adminerInfo();
        }

        if($this->hasRole('worker')){
            return $this->workerInfo();
        }
        return null;
    }

it will give this error -

Call to a member function addEagerConstraints() on null

if I do like this , and If my user is manager . it works

$user = User::find(Auth::user()->id)->load('managerInfo', 'Roles');
 return  new InfoFormREResource($user);

but I wold like to load depends on my user type .

0 likes
3 replies
LaryAI's avatar
Level 58

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:

  1. Modify the UserInfo method to return the relationship name as a string.
  2. 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.

1 like
murilo's avatar
Level 10

thanks @snapey , I managed controlling this on resource -

$user = User::find(Auth::user()->id)->load('managerInfo', 'adminerInfo', 'workerInfo', 'Roles');
 return  new InfoFormResource($user);

the resource -

class InfoFormResource extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            $this->mergeWhen($request->user()->isManager, [
                "manager_info" =>  ......
            ]),
            $this->mergeWhen($request->user()->isWorker, [
                "worker_info" => ......            ]),
           ])
        ];
    }

}

Please or to participate in this conversation.