8
votes

I have a users table and a permissions table. It's a many-to-many relationship so I also have a users_permissions table with a user_id & module_permission_id column.

The user model has the following relationship:

public function permissions()
{
    return $this->belongsToMany(Permission::class, 'users_permissions', 'user_id', 'module_permission_id');
}

When I run my query, the result contains an empty permissions array.

User::with('permissions');

If I echo the query in the with, I get the error: Call to undefined relationship [] on model [App\Models\User]

User::with(['permissions', function($q) {
            echo $q->toSql();  
            die();
        }]);

The rest of the query works, it's just trying to get permissions which is failing.

3
User::with('permissions'); only returns the query builder. Try running User::with('permissions')->get(); and see what it returns. You can also run User::with('permissions')->toSql(); to check if correct query is being formed. - Sandeesh

3 Answers

4
votes

In my case it was a coding convention issue related to camelCase vs. snake_case: In the Model there was

public function getPermissions()

and in the query there was

User::with(['get_permissions'])

When I changed this to

User::with(['getPermissions'])

it started to work, although I'd say the Laravel way would be to use snake_case instead.

This confused me for a couple of days since frameworks like Symfony and AngularJs has a mixed conventions that somewhere you need to write parameters in snake_case and somewhere else in camelCase. I didn't find any documentation on Laravel site how they handle this, so I tried it the Straight Way and it seemed to be the case here :)

2
votes

Maybe you just forgot the ->get() after User::with('permissions')->get() ?

https://laravel.com/docs/5.0/eloquent#eager-loading

1
votes

Slapping this here for anyone who may be trying to refactor from an eager load that selects columns to an eager load with a scoped query.

You HAVE to move the selecting of columns into the scoped query, trying to select columns with the usual colon notation will fail and throw the undefined relationship error.

For example going from this eager load that selects a pivot table column, and a column from the permissions table User:with('permissions:permission_tag:tag_set_id,permission_name') to a scoped query that selects the same columns but also orders the results looks like this

  User::with([
    'permissions' => function ($query) {
      $query->select('permission_tag:tag_set_id', 'permission_name');
      $query->orderBy('permission_name');
    },
  ]);

Notice I pulled out the : notation and it lives right in the scoped query.