Laravel полиморфные отношения многие ко многим - PullRequest
0 голосов
/ 27 февраля 2019

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

Надеюсь, у кого-нибудь есть время, чтобы хоть немного помочь мне разобраться в этом.Я пытаюсь создать очень простую систему тегов для некоторых обоев.

Я запустил новый тестовый проект, чтобы заставить это работать.

У меня есть 3 модели: Обои,Tag and WallpaperTag

class Wallpaper extends Model
{

    protected $primaryKey = 'wallpaper_id';
    protected $table = 'wallpapers';
    protected $guarded = ['wallpaper_id'];

    /**
     * Get all the tags assigned to this wallpaper
     */
    public function tags()
    {
        //
    }

}

class Tag extends Model
{

    protected $primaryKey = 'tag_id';
    protected $table = 'tags';
    protected $guarded = ['tag_id'];

    /**
     * Get all wallpapers that have this given tag
     */
    public function wallpapers()
    {
        //
    }
}

class WallpaperTag extends Model
{

    protected $primaryKey = 'wallpaper_tag_id';
    protected $table = 'wallpaper_tags';
    protected $guarded = ['wallpaper_tag_id'];

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     * Wallpaper relation
     */
    public function wallpaper()
    {
        return $this->belongsTo('App\Wallpaper','wallpaper_id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     * Tag relation
     */
    public function tag()
    {
        return $this->belongsTo('App\Tag','tag_id');
    }

}

Таблица обоев в этом тестовом проекте содержит только wallpaper_id
Таблица тегов contanis a tag_id и tag
Таблица wallpaper_tags содержит внешний ключдля tags.tag_id и wallpapers.wallpaper_id

Я настроил это так, чтобы обои могли обмениваться тегами, не дублируя их.Проблема в том, что я действительно не понимаю полиморфные отношения и пример в документации .

Может ли кто-нибудь здесь «накормить», как это будет работать?: ') Заранее спасибо за помощь.

1 Ответ

0 голосов
/ 27 февраля 2019

Итак, вы пытаетесь создать отношение с ManyToMany между двумя таблицами, которым в БД нужна третья таблица, чтобы позволить вам создать такие отношения.

Это связано с тем, что у одного Wallpaper может быть много Tag и наоборот!Для этого вам понадобится третья таблица, в которой хранится эта информация.

Третья таблица содержит идентификаторы только по отношению к вашим двум основным таблицам.Это обеспечивает гибкость, которую вы ищете, в то время как ваши таблицы объектов могут на самом деле содержать информацию, специфичную для них, без необходимости дублировать ее.

Если вы будете хранить идентификаторы отношений в обеих таблицах, вы будете вынужденыдублируйте ваши данные, и это просто то, что вам не нужно в базах данных!Представьте себе, что вам нужно обновить 1000 строк, потому что это в основном те же обои, но с таким количеством разных тегов.

В любом случае, ниже приведен код, который должен помочь вам:

  1. Вы делаетенеобходимо создать класс для представления вашей таблицы отношений (спасибо классу WallpaperTag! Это тот самый!);
  2. Вы больше не трогаете этот класс, не добавляете принадлежность или любую другую функцию!
  3. Вы создаете отношения на основных классах Wallpaper и Tag;
    class Wallpaper extends Model
    {
        ...
        public function tags()
        {
            return $this->belongsToMany('App\Tag', 'wallpaper_tag', 'tag_id', 'wallpaper_id');
        }
    }

    class Tag extends Model
    {
        ...
        public function wallpapers()
        {
            return $this->belongsToMany('App\Wallpaper', 'wallpaper_tag', 'wallpaper_id', 'tag_id');
        }
    }

    class WallpaperTag extends Model
    {

    }

Laravel должен создать отношения между вашими классами и сопоставить их соответственно с правильной 3-ей таблицейсортировать поиск для вас.

Если вы следуете семантике, все, что вам нужно, это имя класса.Если идентификаторы должны измениться, вам нужно будет сообщить Laravel, какие имена столбцов идентификаторов нужно искать, поскольку вы отклоняетесь от нормального поведения.Это все еще находит это, только нуждается в некотором руководстве относительно имен!Поэтому мы начинаем добавлять дополнительные параметры в отношения belongsTo или hasMany и т. Д.)

Миграция сводной таблицы

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

  $table->bigInteger('wallpaper_id')->unsigned()->nullable();
  $table->foreign('wallpaper_id')->references('wallpaper_id')
        ->on('wallpaper')->onDelete('cascade');

  $table->bigInteger('tag_id')->unsigned()->nullable();
  $table->foreign('tag_id')->references('tag_id')
        ->on('tags')->onDelete('cascade');

Дайте мне знать, если это помогло!: 3

...