Как перейти от строкового столбца к внешнему ключу, указывающему на строку в другой таблице с таким же строковым значением в Laravel? - PullRequest
0 голосов
/ 16 октября 2018

Я использую Laravel 5.6 и мне нужна помощь в переносе столбца из заполненной таблицы с сохранением логики содержимого.Существует таблица pages со столбцом с именем icon, которая принимает значения string.

Пример:

Schema::create('pages', function (Blueprint $table) {
        $table->increments('id');
        ...
        $table->string('icon')->nullable();
}

Таблица pages заполняется, а iconстолбец, имеющий значение NULL, используется не всегда.

Была создана новая таблица icons для хранения всех используемых классов значков.

Пример:

Schema::create('icons', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
});

КакМогу ли я перенести столбец icon из таблицы pages в качестве внешнего ключа, который указывает на строку таблицы icons, имеющую то же значение в столбце name, либо на ноль, если он не заполнен?

1 Ответ

0 голосов
/ 16 октября 2018

Я бы предложил здесь полиморфный many-to-many подход, чтобы icons можно было многократно использовать и не требовало связки сводных таблиц, если вы хотите icons на чем-то отличном от страницы.

Schema::create('icons', function(Blueprint $table) {
    $table->increments('id');
    $table->string('name');
});

Schema::create('iconables', function(Blueprint $table) {
    $table->integer('icon_id');
    $table->integer('iconables_id');
    $table->integer('iconables_type');
});

Теперь вам просто нужно определить, существует ли на страницах Icon.Если это так, удерживайте ссылку на них, чтобы вы могли вставить их:

$pagesWithIcons = Page::whereNotNull('icon')->get();

На данный момент вам нужно определить полиморфные отношения в ваших моделях:

// icon

class Icon extends Model
{
    public function pages()
    {
         return $this->morphedByMany(Page::class, 'iconable');
    }
}

// page

class Page extends Model
{
    public function pages()
    {
         return $this->morphToMany(Icon::class, 'iconable');
    }
}

Теперь вы простонеобходимо создать icons (обратно в нашей миграции), а затем присоединить их, если они существуют:

$pagesWithIcons->each(function(Page $page) {
    $icon = Icon::firstOrNew([
        'name' => $page->icon
    });

    $icon->pages()->attach($page);
});

Выше создается Icon, если он не существует, или запрашивается егоесли это так.Затем он прикрепляет страницу к этому icon.Поскольку полиморфные отношения many-to-many просто используют методы belongsToMany() под капотом, у вас есть все доступные операции на досуге, если это не соответствует вашим потребностям.

Наконец, удалите столбец icons изстраниц, вам это не нужно.

Schema::table('pages', function(Blueprint $table) {
    $table->dropColumn('icon');
});

И если вам нужно заполнить поддержку только для отдельного icon (так как many-to-many теперь будет возвращать отношение массива), вы можете добавитьСледуя вашей page модели:

public function icon()
{
    return $this->icons()->first();
}

Извините, если опечатки, я сделал это на своем телефоне, поэтому могут быть некоторые ошибки.

...