Как получить доступ к пользовательским данным через промежуточную таблицу (hasOneThrough / hasManyThrough)

#laravel #eloquent #relationship #eloquent-relationship

#laravel #красноречивый #взаимосвязь #красноречивое отношение

Вопрос:

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

приложения:

  • идентификатор как первичный ключ
  • job_offer_uuid как внешний ключ

job_offers:

  • uuid как первичный ключ
  • идентификатор пользователя как внешний ключ

Пользователи:

  • Просто таблица обычных пользователей laravel с идентификатором в качестве первичного ключа

Поскольку мне нужно уведомлять владельца job_offer (участника User model) каждый раз, когда регистрируется приложение, я пытаюсь создать связь hasOneThrough или hasManyThrough между приложениями и пользователями, но на данный момент безуспешно.

Пользователь
для пояснения: в модели размещаются только пользователи, которые публикуют предложения о работе, и любой пользователь может опубликовать много предложений о работе. В users таблице нет кандидатов

Основываясь на моем понимании документации eloquent (https://laravel.com/docs/8.x/eloquent-relationships#has-one-through ), мой фактический код в модели приложения:

 public function publisher()
{
    return $this->hasOneThrough(User::class, JobOffer::class, 'job_offer_uuid', 'user_id');
}
 

Но он выдает ошибку SQL:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_offers.job_offer_uuid' in 'field list' (SQL: select `users`.*, `job_offers`.`job_offer_uuid` as `laravel_through_key` from `users` inner join `job_offers` on `job_offers`.`id` = `users`.`user_id` where `job_offers`.`job_offer_uuid` in (1)

используя вместо этого hasManyThrough, я получил идентичную ошибку:

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_offers.job_offer_uuid' in 'field list' (SQL: select `users`.*, `job_offers`.`job_offer_uuid` as `laravel_through_key` from `users` inner join `job_offers` on `job_offers`.`id` = `users`.`user_id` where `job_offers`.`job_offer_uuid` in (1))

Я могу получить точные результаты, используя чистый SQL, с предложением, подобным этому:

select applications.id, applications.job_offer_uuid, job_offers.uuid, job_offers.user_id, users.id, users.name, users.email from `applications` inner join job_offers on `applications`.`job_offer_uuid` = `job_offers`.`uuid` join users on job_offers.user_id = users.id where `applications`.id = 1

Любое видео или учебное пособие, которое я нашел, связанное с этим пунктом, использует конечную таблицу с внешним ключом к промежуточной таблице, и это означает, что моя пользовательская модель должна иметь внешний ключ job_offer_id, но для меня это не имеет смысла.

Любые разъяснения должны быть по-настоящему оценены. С уважением!

Ответ №1:

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

 public function publisher()
{
    return $this->hasOneThrough(
        Application::class,
        JobOffer::class,
        'user_id', // Foreign key on job_offers table
        'job_offer_uuid', // Foreign key on applications table
        'id', // Local key on user table
        'uuid' // Local key on job_offer table
    );
}
 

Комментарии:

1. Спасибо за ваш вклад, Прадип Дарджи, я попробую ваше решение, но, похоже, оно получит доступ к записям приложений, которые принадлежат конкретному пользователю. И в этом случае это должно быть hasManyThrough потому, что пользователь может публиковать много job_offers . С другой стороны, приложение может принадлежать только одному предложению о работе, а предложение о работе может принадлежать только одному пользователю. Это то, чего я могу достичь с помощью моего предложения pure SQL, опубликованного в конце моего вопроса.