What is the MySQL datatype SET equivalent in Laravel Schema?

前端 未结 6 1765
春和景丽
春和景丽 2020-12-15 10:13

Laravel Schema has a command for ENUM equivalent to the table. What is the SET equivalent to the table?

相关标签:
6条回答
  • 2020-12-15 10:49

    Extending laravel database schema methods is not too hard. Like Roman wrote, instead of extending, you can as well update your

    vendor/laravel/framework/src/Illuminate/Database/Schema/Grammers/MysqlGrammer.php

    /**
     * Create the column definition for an set type.
     *
     * @param  \Illuminate\Support\Fluent  $column
     * @return string
    */
    protected function typeSet(Fluent $column){
        return "set('".implode("', '", $column->allowed)."')";
    }

    vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php

    /**
         * Create a new set column on the table.
         *
         * @param  string  $column
         * @param  array   $allowed
         * @return \Illuminate\Support\Fluent
        */
        public function set($column, array $allowed){
            return $this->addColumn('set', $column, compact('allowed'));
        }

    After this, terminate your server by pressing Ctrl + C. Then type php artisan serve to start the laravel.

    0 讨论(0)
  • 2020-12-15 11:00

    As of now Laravel Schema Builder does not support SET datatype for columns. So, here is an alternative solution until someone add those code to Laravel.

    Step 1: Create the table, use ENUM instead of SET.

    Schema::create('schools', function($table)
    {
        $table->increments('id');
        $table->char('id_number', 6);
        $table->string('school_name');
        $table->enum('level', array('Preschool', 'Kindergarten', 'Primary', 'Secondary'))->index(); // *** fix this
        $table->string('phone');
        $table->string('email');
        $table->string('location');
        $table->smallInteger('city')->unsigned()->index();
        $table->smallInteger('country')->unsigned()->index();
        $table->smallInteger('head_teacher')->unsigned()->index();
        $table->smallInteger('director')->unsigned()->index();
        $table->smallInteger('created_by')->unsigned();
        $table->smallInteger('modified_by')->unsigned();
        $table->timestamps();
    });
    

    Step 2: Now change ENUM to SET.

    $table_prefix = DB::getTablePrefix();
    DB::statement("ALTER TABLE `" . $table_prefix . "schools` CHANGE `level` `level` SET('Preschool','Kindergarten','Primary','Secondary');");
    

    If you have a better solution, then please let me know.

    0 讨论(0)
  • 2020-12-15 11:08

    Step 1. Extend default classes(add this code to your migration file after use sections):

    class ExtendedBlueprint extends Blueprint {
    
        /**
         * Create a new set column on the table.
         *
         * @param  string  $column
         * @param  array   $allowed
         * @return \Illuminate\Support\Fluent
         */
        public function set($column, array $allowed)
        {
            return $this->addColumn('set', $column, compact('allowed'));
        }
    
    }
    
    
    class ExtendedMySqlGrammar extends Illuminate\Database\Schema\Grammars\MySqlGrammar {
    
        /**
         * Create the column definition for an set type.
         *
         * @param  \Illuminate\Support\Fluent  $column
         * @return string
         */
        protected function typeSet(\Illuminate\Support\Fluent $column)
        {
            return "set('".implode("', '", $column->allowed)."')";
        }
    
    }
    

    Step 2. Then, we need to change default grammar and blueprint classes to our custom:

    // set new grammar class
    DB::connection()->setSchemaGrammar(new ExtendedMySqlGrammar());
    
    // get custom schema object
    $schema = DB::connection()->getSchemaBuilder();
    
    // bind new blueprint class
    $schema->blueprintResolver(function($table, $callback) {
        return new ExtendedBlueprint($table, $callback);
    });
    
    // then create tables 
    $schema->create('table name', function(ExtendedBlueprint $table)
    {
        $table->increments('id');
        $table->text('sentence');
        $table->string('author')->nullable();
        $table->string('source')->nullable();
        $table->set('difficulty', range(1, 10)); // use our new mysql type 
        $table->boolean('enabled')->default(true);
    });
    

    This method will also work after composer update, because we did not edited any framework code.

    0 讨论(0)
  • 2020-12-15 11:08

    My simple once-off solution when you need to create a custom column without creating additional files to describe extended grammar. Here I add my custom type rsvp_statuses into PostgresGrammar:

        public function up()
        {
            DB::connection()->setSchemaGrammar(new class extends PostgresGrammar {
                protected function typeRsvp_statuses(\Illuminate\Support\Fluent $column)
                {
                    return 'rsvp_statuses';
                }
            });
    
            Schema::create('mytable', function (Blueprint $table) {
                $table->bigIncrements('id');
                //...
                $table->addColumn('rsvp_statuses', 'status');
                $table->timestamps();
            });
        }
    
    0 讨论(0)
  • 2020-12-15 11:13

    Laravel 5.8 and onwards support SET datatype in migration. For latest versions, you would simply need to use set() function:

    // SET equivalent column named flavors
    // Allowed values: strawberry , vanilla
    $table->set('flavors', ['strawberry', 'vanilla']);
    

    Check more details at latest documentation:

    • https://laravel.com/docs/master/migrations
    • https://laravel.com/api/master/Illuminate/Database/Schema/Blueprint.html#method_set
    0 讨论(0)
  • 2020-12-15 11:13

    Roman Nazarkin's method works almost perfectly however there is a small issue with table prefixes (which this method does not account for) it is simple however to make this suggestion work with table prefixes:

    $grammar = DB::connection()->withTablePrefix(new ExtendedMySqlGrammar());
    // set new grammar class
    DB::connection()->setSchemaGrammar($grammar);
    
    // get custom schema object
    $schema = DB::connection()->getSchemaBuilder();
    
    // bind new blueprint class
    $schema->blueprintResolver(function($table, $callback) {
        return new ExtendedBlueprint($table, $callback);
    });
    
    // then create tables 
    $schema->create('table name', function(ExtendedBlueprint $table)
    {
        $table->increments('id');
        $table->text('sentence');
        $table->string('author')->nullable();
        $table->string('source')->nullable();
        $table->set('difficulty', range(1, 10)); // use our new mysql type 
        $table->boolean('enabled')->default(true);
    });
    
    0 讨论(0)
提交回复
热议问题