Laravel получает отношения второго уровня

У меня есть три таблицы базы данных:

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

У каждого пользователя может быть много типов, но у одного типа пользователя может быть только один пользователь. Для хранения этого отношения я использую третью таблицу отношений со следующей структурой:

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

Я определил отношения в своих моделях так:

User модель:

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

UserType модель:

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

UserTypeRelations модель:

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

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

И вот как я пытаюсь получить доступ к типу пользователя определенного пользователя в моем контроллере, прежде чем передать его в представление:

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

Я думал, что сначала я получу значение таблицы отношений, и из этого я легко получу тип пользователя для каждого пользователя, но я получаю следующую ошибку:

BadMethodCallException

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

Что я делаю не так?


person Peter    schedule 21.04.2015    source источник


Ответы (2)


Вы можете с готовностью загрузить несколько вложенных отношений в модель, передав их оба одному вызову with:

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

Источник

person Jeff Lambert    schedule 21.04.2015
comment
Спасибо, не знал этого. Извините, если я неясно выразился, но я хочу сначала получить userTypeRelation, а из возвращаемого идентификатора получить тип пользователя. Вот почему я назвал его второй уровень (не уверен, что это правильный термин). - person Peter; 21.04.2015
comment
+ Я изменил свой код одним вызовом with, но все равно получаю ту же ошибку - person Peter; 21.04.2015
comment
Хорошо, я обновил код. Я считаю, что в документации Laravel эти отношения называются вложенными. Посмотрите, работает ли это для вас. - person Jeff Lambert; 21.04.2015

Я считаю, что ваши отношения неправильны. На самом деле это отношение «многие ко многим», что означает, что вы можете полностью избавиться от UserTypeRelations.

Итак, с учетом сказанного, удалите UserTypeRelations.php, а затем притворитесь, что отношения больше не существует. Laravel позаботится об этой таблице за вас.

Затем в вашей пользовательской модели создайте функцию...

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

И в вашей модели UserType добавьте функцию...

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

Теперь это больше не вложенное отношение.

$user = User::with('types')->find($id);
foreach($user->types as $type) {
    echo $type;
}
person user1669496    schedule 21.04.2015
comment
Хороший улов, я считаю, что это лучше для ОП - person Jeff Lambert; 22.04.2015