5

I have three database tables:

+------+-----------+---------------------+
| user | user_type | user_type_relations |
+------+-----------+---------------------+

Each user can have many types, but one user type can only have one user. To store this relation, I use a third relationship table, with the following structure:

+---------------------+
| user_type_relations |
+---------------------+
| id                  |
| user_id             |
| user_type_id        |
+---------------------+

I have defined the relations in my models like so:

User model:

public function userTypeRelations()
    {
        return $this->hasMany('UserTypeRelations', 'user_id', 'id');
    }

UserType model:

public function userTypeRelation()
    {
        return $this->hasMany('UserTypeRelations', 'user_type_id', 'id');
    }

UserTypeRelations model:

 public function user()
    {
        return $this->hasMany('User', 'id', 'user_id');
    }

    public function userType()
    {
        return $this->hasMany('UserType', 'id', 'user_type_id');
    }

And this is how I try to access the user type of a specific user in my controller, before passing it to a view:

$users = User::with('userTypeRelations')->with('userType')->orderBy($order)->where('status', 'active')->paginate(10);

I thought that first I get the relation table's value, and from that I'll easily get the User Type of each User, but I get the following error:

BadMethodCallException

Call to undefined method Illuminate\Database\Query\Builder::userType() 

What am I doing wrong?

Peter
  • 233
  • 2
  • 4
  • 8

2 Answers2

9

You can eager load multiple nested relations to a model by passing them both to a single call to with:

User::with('userTypeRelations.userType') ...

Source

Jeff Lambert
  • 24,395
  • 4
  • 69
  • 96
  • Thanks, didn't know this. Sorry if I wasn't clear, but what I want to do is to first get the userTypeRelation, and from the ID that comes back, get the user type. So this is why I called it _second level_ (not sure if the term is correct). – Peter Apr 21 '15 at 20:30
  • + I modified my code with a single call to `with`, but I still get the same error – Peter Apr 21 '15 at 20:31
  • Ok I updated the code. I believe in the Laravel docs they're calling these _nested_ relationships. See if that works for you. – Jeff Lambert Apr 21 '15 at 20:34
3

I believe your relationships are wrong. This is actually a many to many relationship which means you can get rid of your UserTypeRelations all together.

So with that said, delete UserTypeRelations.php and then pretend that relation no longer exists. Laravel will handle that table for you.

Then in your user model, create the function...

public function types()
{
    return $this->belongsToMany('UserType', 'user_type_relations','user_type_id', 'user_id');
}

And in your UserType model add the function...

public function users()
{
    return $this->belongsToMany('User', 'user_type_relations', 'user_id', 'user_type_id');
}

Now it's no longer a nested relation.

$user = User::with('types')->find($id);
foreach($user->types as $type) {
    echo $type;
}
user1669496
  • 32,176
  • 9
  • 73
  • 65