Laravel — имеет одно отношение, основанное на атрибуте модели

#php #laravel

Вопрос:

У меня проблема, мне нужно создать отношение на основе атрибута из модели $this->type , мой код выглядит следующим образом:

 class Parent extends Model {

    protected $attributes = [
        'type' => self::TYPE_A 
    ];

    public function child()
    {
        return match ($this->type) {
            self::TYPE_A => $this->hasOne(Cousin::class)->where('type', Cousin::TYPE_A),
            self::TYPE_B => $this->hasOne(Cousin::class)->where('type', Cousin::TYPE_B),
            self::TYPE_C,
            self::TYPE_D => $this->hasOne(Cousin::class)->where('type', Cousin::TYPE_C),
            self::TYPE_E,
            self::TYPE_F => $this->hasOne(Cousin::class)->where('type', Cousin::TYPE_D)
        };
    }

    public function children()
    {
        return $this->hasMany(Cousin::class);
    }

}
 

Если я сделаю это внутри artisan tinker , я правильно пойму отношение к ребенку:

 $parent = Parent::first();

$parent->child;
 

Однако, если мои очереди выполняют код child , отношение возвращается как null .

Если я введу logger($this) первую строку отношения, я получу пустую модель внутри очередей:

[2021-09-29 23:51:59] local.DEBUG: {"type":1}

Есть идеи, как это решить?

Ответ №1:

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

Отношения, которые я хочу, используют составные ключи, и Красноречивый не поддерживает их.

Они создали пакет, чтобы это произошло: https://github.com/topclaudy/compoships

Но я не хочу добавлять больше пакетов в свое приложение, так как оно и так слишком большое.

Мое решение состояло в том, чтобы добавить еще один столбец в cousins таблицу, чтобы знать, какой из них использовать:

 public function child() {
    return $this->hasOne(Cousin::class)
        ->where('main', true);
}
 

Ответ №2:

 protected $attributes = [
    'type'
];

public function getTypeAttribute() {
        return $this->hasOne(Cousin::class)
            ->where('main', true);
}
 

Тогда звоните куда угодно

 $parent->type
 

Или вы можете сделать это следующим образом

 public function typeMainTrue() {
        return $this->hasOne(Cousin::class)
            ->where('main', true);
}
 

Тогда звоните куда угодно

 $parent->typeMainTrue