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

Orgil's avatar
Level 2

Eagear Loading Multiple tables

I have following 3 tables with relationship. How can I make eager load these ? Even it is working fine with query builder, I want more perforemance.

Permission

class Permission extends Model
{
    public function user_profiles()
    {
      return $this->belongsTo('App\UserProfile');
    }
}

User

class User extends Model
{
    public function user_profiles()
    {
        return $this->belongsTo('App\UserProfile');
    }
}

UserProfile

class UserProfile extends Model
{
    public function users()
    {
        return $this->hasMany('App\User');
    }

    public function permissions()
    {
      return $this->hasMany('App\Permission');
    }
}

How to convert this Query builder to Eager Load

  $this->menus = DB::table('users')
                 ->join('user_profiles', 'user_profiles.id', '=', 'users.user_profiles_id')
                 ->join('permissions', 'user_profiles.id', '=', 'permissions.user_profiles_id')
                 ->where('users.id', '=', $this->currentUser)
                 ->select('users.id', 'users.username', 'user_profiles.title', 'permissions.page_name', 'permissions.page', 'permissions.view', 'permissions.submit', 'permissions.print')
                 ->get()->all();

I tried as follows, But it does not work

$this->menus = User::with(['user_profiles' => function ($q) {
         $q->select('title');
      }, 'user_profiles.permissions' => function ($q) {
         $q->select('page_name', 'page', 'view', 'submit', 'print');
      }])->where('id', $this->currentUser)->get(['id', 'username'])->all();
0 likes
6 replies
rwdevguy's avatar

You'll have to include the id's in your selects as well otherwise Eloquent won't know what to put where.

Orgil's avatar
Level 2

@rosswilson252 I updated as follows

$this->menus = User::with(['user_profiles' => function ($q) {
         $q->select('id', 'title');
      }, 'user_profiles.permissions' => function ($q) {
         $q->select('id', 'user_profiles_id', 'page_name', 'page', 'view', 'submit', 'print');
      }])->where('id', $this->currentUser)->get(['id', 'user_profiles_id', 'username'])->all();

That gives error

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'permissions.user_profile_id' in 'where clause' (SQL: select `id`, `user_profiles_id`, `page_name`, `page`, `view`, `submit`, `print` from `permissions` where `permissions`.`user_profile_id` in (1))
larafever's avatar

try this is more eloquent approach

class Permission extends Model
{
    public function user_profiles()
    {
      return $this->belongsTo('App\UserProfile','user_profiles_id');
// just add second param and this will reference a foreign key column that connects the permissions model and the users profile
    }
}

user

class User extends Model
{
    public function user_profiles()
    {
        return $this->hasOne('App\UserProfile','user_profiles_id','id');
//the relationship should be user has one userprofile using the fk column user_id in the userprofile table and id in the user table
    }
}

userprofile

class UserProfile extends Model
{
    public function users()
    {
        return $this->belongsTo('App\User','user_id');
//relationship is userprofile belongsTo one user, profile cannot be possessed by multiple users
    }

    public function permissions()
    {
      return $this->hasMany('App\Permission','user_profiles_id','id');
    }
}

I don't really know how you want to implement the permissions on users, if users are assign to multiple permission then the above will work fine.

Now eager load

$this->menus = User::select('id', 'username')->with('user_profiles.permissions')->get();

We don't need to do more join join since we have our eloquent relationships but not that all but not $hidden`` columns in bothuser_profilesmodel andpermission``` model will be fetched.. We can hide columns that are irrelevant to most of our queries by using the

class UserProfile extends model{

    protected $hidden = ['your_columns_that_are_irrelevant'];
}

Hope it helps

Orgil's avatar
Level 2

@larafever Following query only return UserProfile columns not selected columns

$this->menus = UserProfile::with(['permissions' => function ($q) {
      $q->select('id', 'page_name', 'page', 'view', 'submit', 'print', 'user_profiles_id');
   }])->get()->all();

Do you have any idea why ?

EventFellows's avatar

Not sure if that is the cause but you probably only want to use ->get() OR ->all() and not both at the same time.

larafever's avatar

Try this

$this->menus = UserProfile::with(['permissions' => function ($q) {
      $q->select('id', 'page_name', 'page', 'view', 'submit', 'print', 'user_profiles_id')->first();
   }])->get();

Please or to participate in this conversation.