Laravel - Получить опорную связь - PullRequest
1 голос
/ 08 мая 2020

У меня есть следующая схема базы данных:

users
    id

skills
    id

skill_user
    id
    user_id
    skill_id

endorsements
    id
    skill_user_id

Модели Laravel определены следующим образом:

class User extends Authenticatable
{
    public function skills()
    {
        return $this
            ->belongsToMany('App\Skill')
            ->using(SkillUser::class)
            ->withPivot('endorsements_count')
            ->orderBy('endorsements_count', 'desc');
    }

}

class Skill extends Model
{
    public function users()
    {
        return $this
            ->belongsToMany('App\User')
            ->using(SkillUser::class)
            ->withPivot('user_id');
    }
}

class SkillUser extends Pivot
{
    public function endorsements()
    {
        return $this->hasMany('App\Endorsement', 'skill_user_id', 'id');
    }
}

class Endorsement extends Model
{
    public function skill_user() {
        return $this->belongsTo('App\SkillUser');
    }
}

Из приведенного выше вы можете видеть, что user может иметь несколько skills, соединенных с помощью таблицы «многие ко многим», называемой SkillUser. Кроме того, навыки каждого пользователя могут быть одобрены другими пользователями (endorsement). endorsements объединены в сводной таблице (каждый user_skill может иметь несколько подтверждений).

Теперь я пытаюсь понять, как построить запрос в Laravel (Eloquent), который будет получать пользователей с все его навыки и для каждого навыка, все его подтверждения в ОДНОМ запросе.

Когда я делаю следующее:

User::with('skills')->findOrFail(1)->skills[0]->pivot->endorsements

Он правильно возвращает пользователя и информацию о навыках, но подтверждения внутри точки поворота (UserSkill) пустые. Кроме того, когда я проверяю отношения pivot->, они также пусты.

С другой стороны, если я запрошу вот так:

SkillUser::where('id', '=', 1)->first()->endorsements

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

Любая помощь будет принята с благодарностью!

1 Ответ

1 голос
/ 10 мая 2020
class Skill extends Model
{
    public function endorsements()
    {
        return $this->hasMany(Endorsement::class, 'skill_user_id');
    }
}
class Endorsement extends Model
{
    public function user()
    {
        return $this->hasOne(User::class, 'id', 'user_id')->select(['id', 'firstname', 'lastname']);
    }
}
class User extends Model
{
    public function skills()
    {
        return $this->belongsToMany(Skill::class)->using(SkillUser::class)->select(['skill_user.id']);
    }
}

Я добавил endorser столбец в endorsements таблицу для связи с пользователем.

return User::with('skills.endorsements.user')->findOrFail(1, ['id', 'name']);

он печатает что-то вроде этого:

{
  "id": 1,
  "name": "my-user",
  "skills": [
    {
      "id": 1,
      "name": "askill",
      "pivot": {
        "user_id": 1,
        "skill_id": 1
      },
      "endorsements": [
        {
          "id": 1,
          "skill_user_id": 1,
          "endorser": 2,
          "user": {
            "id": 2,
            "name": "user-2"
          }
        },
        {
          "id": 2,
          "skill_user_id": 1,
          "endorser": 3,
          "user": {
            "id": 3,
            "name": "user-3"
          }
        }
      ]
    },
    {
      "id": 2,
      "name": "bskill",
      "pivot": {
        "user_id": 1,
        "skill_id": 2
      },
      "endorsements": [
        {
          "id": 3,
          "skill_user_id": 2,
          "endorser": 2,
          "user": {
            "id": 2,
            "name": "user-2"
          }
        }
      ]
    },
    {
      "id": 4,
      "name": "dskill",
      "pivot": {
        "user_id": 1,
        "skill_id": 4
      },
      "endorsements": []
    }
  ]
}

вот запросы, выполняемые за кулисами;

SELECT `id`, `name`
FROM `users`
WHERE `users`.`id` = '1'
LIMIT 1;

SELECT `skills`.*, `skill_user`.`user_id` as `pivot_user_id`, `skill_user`.`skill_id` as `pivot_skill_id`
FROM `skills`
         inner join `skill_user` on `skills`.`id` = `skill_user`.`skill_id`
WHERE `skill_user`.`user_id` in ('1');

SELECT *
FROM `endorsements`
WHERE `endorsements`.`skill_user_id` in ('1', '2', '4');

SELECT `id`, `name`
FROM `users`
WHERE `users`.`id` in ('2', '3');

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...