Как написать отношение к удаленной модели через полиморфное отношение - PullRequest
1 голос
/ 09 апреля 2019

У меня есть полиморфное отношение, в котором класс (Request) может иметь отношение либо с классом (Leave), либо с классом (Overtime).

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

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


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

  • Запрос класса с:
    • user_id
    • requesttable_id
    • requesttable_type может быть 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;

Ответы [ 3 ]

0 голосов
/ 09 апреля 2019

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

$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');
}
0 голосов
/ 10 апреля 2019

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

Использование 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); 
}
0 голосов
/ 09 апреля 2019

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

...