how can I create a migration to add a value to an enum in eloquent
Asked Answered
W

6

38

I have a table that contains an enum field

CREATE TABLE `user_status` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `values` enum('on', 'off'),
  PRIMARY KEY (`id`),
) ENGINE=InnoDB;

how can I create a migration to add a value to the enum field?

Woodcut answered 19/2, 2014 at 5:46 Comment(1)
The doctrine docs have something to say about ENUMs and why they are not so good supported: docs.doctrine-project.org/projects/doctrine-orm/en/latest/…Detrition
G
74

Laravel doesn't provide methods to update an enum column. You can delete and recreate the column but you could loose data during the operation and it's not really clean.

In this case, I think that the best choice is to write raw SQL into a migration :

public function up()
{
    DB::statement("ALTER TABLE user_status MODIFY COLUMN ENUM('on','off','unknown')");
}

public function down()
{
    DB::statement("ALTER TABLE user_status MODIFY COLUMN ENUM('on','off')");
}

I could have made a mistake in the SQL syntax, I have never used ENUM, but you can see the idea anyway.

Growth answered 19/2, 2014 at 18:57 Comment(6)
Be aware that you can only support databases that support the ENUM type with this solution. For example, running tests with SQLite will break.Aaren
Is it still the "best" way to write raw SQL DDL if you have no idea what database platform the migration will be run on?Maquette
Any migration name convention for this?Going
Thanks for this. I put my column name at COLUMN the values part is causing a syntax error you could remove it.Proclitic
Running "php artisan migrate" gives me "Nothing to migrate". Should I go for manual update in my localhost after updating here?Astonishing
Just to add an advice in case someone else faces the problem I was facing: in case you try this solution and see an "SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax;" your problem might be that the column name of the enum column that you're trying to update is one of the many MySQL Keywords and Reserved Words (more here)Angelita
P
6

I did it with MySql:

class ChangeJobTypeEnum extends Migration {

    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        DB::statement("ALTER TABLE _TABLENAME_ CHANGE _COLUMNNAME_ _COLUMNNAME_ ENUM('on', 'off', 'auto')");

    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        DB::statement("ALTER TABLE _TABLENAME_ CHANGE _COLUMNNAME_ _COLUMNNAME_ ENUM('on', 'off')");

    }
}
Pentateuch answered 26/2, 2016 at 13:56 Comment(0)
H
2

I had a slightly different situation, it was necessary to add new items, change existing and remove old. This is my example.

 <?php

    use Illuminate\Support\Facades\Schema;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Database\Migrations\Migration;

class ChangeEnum extends Migration
{   
    public function up()
    {
        Schema::table('table_example', function (Blueprint $table) {
            DB::statement("ALTER TABLE table_example MODIFY status enum('first', 'second', 'third', 'fourth', 'fifth', 'sixth') NOT NULL;");
            DB::statement("UPDATE `field` set `status` = 'fourth' where `status` = 'first';");
            DB::statement("UPDATE `field` set `status` = 'fifth' where `status` = 'second';");
            DB::statement("ALTER TABLE table_example MODIFY status enum('third', 'fourth', 'fifth', 'sixth') NOT NULL;");
        });
    }

    public function down()
    {
        Schema::table('table_example', function (Blueprint $table) {
            DB::statement("ALTER TABLE table_example MODIFY status enum('first', 'second', 'third', 'fourth', 'fifth', 'sixth') NOT NULL;");
            DB::statement("UPDATE `field` set `status` = 'first' where `status` = 'fourth';");
            DB::statement("UPDATE `field` set `status` = 'second' where `status` = 'fifth';");
            DB::statement("ALTER TABLE table_example MODIFY status enum('first', 'second', 'third',) NOT NULL;");
        });
    }
}

By the way, generate row SQL query via JetBrains ide(DataGrip), is like that:

 ∧_∧ 
(。・ω・。)つ━☆・*。
⊂   ノ    ・゜+.
 しーJ   °。+ *´¨)
Heliacal answered 11/10, 2018 at 17:39 Comment(0)
C
1

The second answer works, but in my case CHANGE was throwing an error. So i tried using MODIFY instead and that worked. Thanks guys..

Here is my code:

class ChangeJobTypeEnum extends Migration {

/**
 * Run the migrations.
 *
 * @return void
 */
public function up()
{
    DB::statement("ALTER TABLE _TABLENAME_ MODIFY _COLUMNNAME_ ENUM('on', 'off', 'auto')");

}

/**
 * Reverse the migrations.
 *
 * @return void
 */
public function down()
{
    DB::statement("ALTER TABLE _TABLENAME_ MODIFY_COLUMNNAME_ ENUM('on', 'off')");

}
}
Camphorate answered 21/6, 2019 at 9:14 Comment(0)
B
1

I say

public function up()
    {
        Schema::create('dt_warehouses', function (Blueprint $table) {
            **$table->enum('isactive', ['Y', 'N'])->default('Y');**
            $table->timestamps();
        });
    }
Baedeker answered 6/10, 2020 at 3:19 Comment(0)
S
0

Since Laravel v10 a new change() modifier is available, so it is no longer needed to use SQL to update enum items.

https://laravel.com/docs/11.x/migrations#modifying-columns

E.g.:

Schema::table('users', function (Blueprint $table) {
    $table->enum('role', ['admin', 'user', 'contributor'])->change();
});
Spier answered 26/6 at 22:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.