I am using Laravel 5.1 and I have a table called packages with this structure:
id int(11)
weight decimal(10,2)
weight_unit e
This worked for me when adding a new enum value to the modified enum column.
Add the following to the up()
method:
DB::statement("ALTER TABLE packages MODIFY weight_unit ENUM('Grams', 'Kgs', 'Pounds', 'new value') NOT NULL");
Then in the down()
method you can revert the change that was made:
DB::statement("ALTER TABLE packages MODIFY weight_unit ENUM('Grams', 'Kgs', 'Pounds') NOT NULL");
Note: before the enum value is removed it needs to be changed to another enum value that will be retained.
add this before change() call :
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
Use the DB::statement
method:
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
In case you dont want to lose your data and update it with the new values I came up with this solution:
// Include old and new enum values
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Kg.', 'Gm.', 'Grams', 'Kgs', 'Pounds')");
// Replace Kg. with Kgs
Packages::where('weight_unit', 'Kg.')->update(['weight_unit' => 'Kgs']);
// Replace Gm. with Grams
Packages::where('weight_unit', 'Gm.')->update(['weight_unit' => 'Grams']);
// Delete old values
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
This way you can replace your old values with the new ones.
You can add custom constructor to migration and explain to Doctrine that enum
should be treated like string.
public function __construct(\Doctrine\DBAL\Migrations\Version $version)
{
parent::__construct($version);
$this->platform->registerDoctrineTypeMapping('enum', 'string');
}
$table->enum('level', ['easy', 'hard']);