Laravel Polymorphic HasOne, модели двух разных категорий для одного и того же элемента

Я пытаюсь использовать две разные модели категорий для одной и той же таблицы items.

у меня 3 модели

Категория системы

Schema::create('system_categories', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->timestamps();
    });

Категория пользователя

Schema::create('user_categories', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->integer('user_id');
        $table->timestamps();
    });

Вещь

Schema::create('items', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->integer('categoryable_id');
        $table->string('categoryable_type');
        $table->timestamps();
    });

Категория элемента может быть из таблицы system_categories или user_categories.

Я видел некоторые полиморфные отношения, но они о том, как две разные модели могут принадлежать к одной категории, а не о том, как модель может принадлежать к двум моделям разных категорий.

Спасибо.


person SrMissAlot    schedule 07.06.2020    source источник
comment
Сколько SystemCategory/UserCategory может быть у Item?   -  person Rwd    schedule 07.06.2020
comment
один. только один тип одного из них @Rwd   -  person SrMissAlot    schedule 07.06.2020
comment
Здесь определенно можно использовать полиморфные отношения. Item будет иметь отношение morphTo, а модели категорий будут иметь отношение morphMany.   -  person Rwd    schedule 07.06.2020
comment
У меня возникли некоторые проблемы, можете ли вы уточнить, пожалуйста? добавил схему к вопросу @Rwd   -  person SrMissAlot    schedule 07.06.2020
comment
Проблема, с которой вы столкнулись, называется polymorphic associations. Пожалуйста, проверьте здесь stackoverflow.com/a/441111/2188922 - это предполагает, что вместо сохранения столбца одного типа + внешний ключ (для нескольких таблиц) - предлагается использовать два столбца внешнего ключа (обнуляемые) для двух разных таблиц. Если вы все еще хотите реализовать свой путь; пожалуйста, проверьте этот раздел laravel.com/docs/7.x/   -  person Ersoy    schedule 07.06.2020
comment
@Ersoy OP использует Laravel, который использует полиморфные отношения из коробки.   -  person ColinMD    schedule 07.06.2020
comment
@ColinMD, если вы продолжите читать, вы увидите, хотите ли вы по-прежнему реализовать ... часть, которая ведет на веб-сайт laravel, который показывает, что я знаю об этом.   -  person Ersoy    schedule 07.06.2020
comment
@Ersoy извинения, я перестал читать, когда вы рекомендовали сделать что-то отличное от того, что фреймворк делает из коробки.   -  person ColinMD    schedule 07.06.2020


Ответы (1)


Это можно сделать, во-первых, ваша схема выглядит нормально, но вы хотите установить для catagoryable_id значение bigInteger, чтобы оно соответствовало столбцам идентификаторов таблиц 2 категорий.

Затем вы бы настроили свои модели

class Item extends Model
{
    public function categoryable() 
    {
        return $this->morphTo();
    }
}

class SystemCategory extends Model
{
    public function items()
    {
        return $this->morphMany('App\Item', 'categoryable');
    }
}

class UserCategory extends Model
{
    public function items()
    {
        return $this->morphMany('App\Item', 'categoryable');
    }
}

Очевидно, это предполагает, что ваши модели находятся в пространстве имен приложений.

person ColinMD    schedule 07.06.2020
comment
Спасибо, это работает !! только что изменено на $this-›morphOne('App\Item', 'categoryable'); - person SrMissAlot; 07.06.2020
comment
Вы можете использовать morphOne, но если item1 и item2 имеют одинаковую системную категорию, то вызов item(s) вернет только одну из этих записей item. - person ColinMD; 07.06.2020
comment
Присоединение используется только в функции «Многие ко многим», где у вас есть сводная таблица. Вместо этого вы должны использовать метод сохранения. $Item-›categoryable()-›save($Category); - person ColinMD; 07.06.2020
comment
Да, я нашел ответ на этот вопрос: $Item-›categoryable()-›associate($Category); - person SrMissAlot; 07.06.2020