Как написать отношение к удаленной модели через полиморфное отношение

У меня есть полиморфное отношение, в котором класс (запрос) может иметь отношение либо к классу (отпуск), либо к классу (сверхурочная работа).

Каждый объект класса (Запрос) принадлежит пользователю.

Я хотел бы установить отношения в классе User, чтобы напрямую получать все их объекты Leave или Overtime.


Вот как выглядит код:

  • Запрос класса с:
    • ID пользователя
    • запрашиваемый_id
    • запрашиваемый_тип может быть App\Leave или App\Overtime
    class Request extends Model
    {
        public function requestable() {
            return $this->morphTo();
        }

        public function user() {
            return $this->belongsTo('App\User');
        }
    }

  • Выход из класса
    class Leave extends Model
    {
        public function request() {
            return $this->morphOne('App\Request', 'requestable');
        }
    }

  • Класс Сверхурочные
    class Overtime extends Model
    {
        public function request() {
            return $this->morphOne('App\Request', 'requestable');
        }
    }

  • Пользователь класса
    class User extends Authenticatable
    {
        public function requests() {
            return $this->hasMany(Request::class);
        }

        public function leaves() {
            // Need help here
        }

        public function overtimes() {
            // And here
        }
    }


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

    $userLeaves = $user->leaves;
    $userOvertimes = $user->overtimes;

Является ли отношение hasManyThrough тем, что вы ищете? laravel.com/docs/5.8/eloquent-relationships#имеет много сквозных‌​. Или вы можете использовать ->hasMany()->where();

LucyTurtle 09.04.2019 20:49

Не могли бы вы попробовать? Я не думаю, что это работает с полиморфными отношениями.

user1717018 09.04.2019 23:15
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
2
93
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Кажется, вам нужна комбинация полиморфного отношения (которое вы уже определили) и hasManyThrough. return $this->hasManyThrough(Leave::class, Request::class); а также return $this->hasManyThrough(Overtime::class, Request::class); соответственно. Но проверьте внешние и локальные ключи (см. подробнее здесь).

Да, я считаю, что hasManyThrough — это решение, но независимо от того, сколько комбинаций я пробовал с иностранными/локальными ключами, я не мог заставить его работать, может быть, попробовать?

user1717018 09.04.2019 23:11

Я никогда не пользовался такими отношениями. Возможно, вам нужно указать тип связанной полиморфной модели. Попробуйте использовать это.

Petr 09.04.2019 23:24

вы можете получить пользовательские листья и сверхурочные через пользовательские запросы, используя

$requests = $user->requests->with('requestable');

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

Класс пользователя

public function leaves()
{
    return $this->requests->where('requestable_type', 'App\Leave');
}

public function overTimes()
{
    return $this->requests->where('requestable_type', 'App\OverTime');
}

Но это вернет объекты типа Request, а не объекты отпуска или сверхурочной работы.

user1717018 09.04.2019 23:05
Ответ принят как подходящий

Отвечая на мой собственный вопрос.

Использование hasManyThrough:

public function leaves() {
    return $this->hasManyThrough(
        Leave::class, // the class that we want objects from
        Request::class, // the class sitting between this one and the target
        'user_id', // this class's foreign key in the request class
        'id', // foreign key in leave class
        'id', // local key in this class
        'requestable_id' // key of the leave in the request class
        )
        // we have to limit it to only Leave class
        ->where('requestable_type', array_search(Leave::class, Relation::morphMap()) ?: Leave::class);
}

public function overtimes() {
    return $this->hasManyThrough(
        Overtime::class, // the class that we want objects from
        Request::class, // the class sitting between this one and the target
        'user_id', // this class's foreign key in the request class
        'id', // foreign key in overtime class
        'id', // local key in this class
        'requestable_id' // key of the overtime in the request class
        )
        // we have to limit it to only overtime class
        ->where('requestable_type', array_search(Overtime::class, Relation::morphMap()) ?: Overtime::class); 
}

Пожалуйста, пометить ответ как принятый. Это показывает другим пользователям, что проблема решена.

Jonas Staudenmeir 17.04.2019 14:09

Другие вопросы по теме