Laravel 5.8: как скопировать значения из старой колонки в новую во время миграции?

Ситуация: во время разработки проекта на Laravel возникла необходимость заменить один столбец другим. Для этого нужно написать миграцию.

Задача: создать столбец, в который переместить значения из ненужного, а затем удалить ненужный.

Решение: очень простое и очевидное — изменить схему, записать значения, изменить схему. Далее привожу пример готовой заготовки миграции:

<?php

use App\MyModel; // модель данных необходимой таблицы
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;

class NewFieldMigration extends Migration
{
    public function up()
    {
        // 1. Создаём поле в таблице

        Schema::table('some_table',function(Blueprint $table) {
            $table->text('new_field')->nullable();
        });

        // 2. Пишем значения из старого поля в новое
        // Обрати внимание на конструкцию update()
        // ВАЖНО: не пытайся сделать это внутри метода Schema::table(),
        // т.к. новое поле не появится пока этот метод не выполнится,
        // и ты словишь исключение mysql при попытке записи в несуществующее поле

        MyModel::query()->update([
            "new_field" => DB::raw("`old_field`"),
        ]);

        // 3. Удаляем ненужное поле

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

    // откат миграции аналогичен, в обратном порядке
    public function down()
    {
        Schema::table('some_table',function(Blueprint $table) {
            $table->string('old_field')->nullable();
        });
        MyModel::query()->update([
            "old_field" => DB::raw("`new_field`"),
        ]);
        Schema::table('some_table',function(Blueprint $table) {
            $table->dropColumn("new_field");
        });
    }
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *