Laravel ha un <seleccione> form helper que toma como entrada un diccionario. Me gusta mantener los valores de todas estas en un lugar central. Por ejemplo, podría haber una enumeración que se parece a esto:

$phoneTypes = [
    'CELL' => "Cellular",
    'HOME' => "Home",
    'WORK' => "Work",
];

Que quiero usar tanto en mi punto de vista/de la plantilla, y en la base de datos:

Schema::create('customers', function (Blueprint $table) {
    $table->increments('id');
    $table->enum('pri_phone_type',array_keys($phoneTypes));
    ...
});
  1. Hay un lugar recomendado para poner estas?
  2. Puedo hacerlos globales, de manera que pueda acceder a ellos fácilmente en todos mis puntos de vista?
InformationsquelleAutor mpen | 2014-09-07

6 Comentarios

  1. 53

    Usted tiene varias opciones para el manejo de las enumeraciones. Antes de mirar un par a pesar de que, en primer lugar, recomendamos que no usar la DB enum tipo de columna.

    Base de datos de las enumeraciones son problemáticos para un número de razones. Sugiero la lectura de este artículo, por ejemplo:

    http://komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil/

    Así que con que echemos un vistazo a un par de otras opciones.

    Usando Laravel config

    Ya que usted está usando Laravel, uno muy simple opción es pegar una gran variedad de opciones en un archivo de configuración.

    Decir crear un nuevo archivo config/enums.php con los siguientes:

    return [
        'phone_types' => [
            'CELL' => "Cellular",
            'HOME' => "Home",
            'WORK' => "Work",
        ]
    ];

    Usted puede ahora tener acceso a config('enums.phone_types') en cualquier lugar en el código, incluyendo la Hoja de la plantilla.

    El uso de un paquete PHP

    @Banford la respuesta se muestra cómo realizar operaciones básicas de enum-tipo de comportamiento con constantes de clase. Si te gusta ese enfoque, te recomiendo mirar este artículo y el paquete que se basa en este concepto para proporcionar fuertemente tipo de enumeraciones:

    https://stitcher.io/blog/php-enums

    https://github.com/spatie/enum

    Habría que crear una clase como esta:

    /**
     * @method static self cell()
     * @method static self home()
     * @method static self work()
     */
    class PhoneTypes extends Enum
    {
    }

    Y ahora usted puede llamar a PhoneTypes::home() en su aplicación. Echa un vistazo a la documentación para que el paquete para ver cómo se puede crear un mapa de valores, si se quiere.

    El uso de DB relaciones

    Si realmente desea administrar sus opciones en la base de datos, me gustaría crear una phone_types tabla de base de datos y crear una relación con su customers tabla. Este es todavía una opción mucho mejor que el uso de enum tipo de columna.

    • ¿Por qué prefiere usted para crear tablas separadas para cada uno de una docena de pequeñas listas que muy rara vez cambio?
    • Entre otras cosas, me pueden consultar para los clientes que tienen un teléfono celular en el archivo? Y el momento en que estoy convencido de que algo no va a cambiar… lo hace. Prefiero el diseño de antelación por lo que es trivial para realizar el cambio, personalmente.
    • Debo aclarar: ciertamente hay veces cuando tengo un varchar tipo de columna con un conjunto de valores posibles que mi controles de aplicación. Sin embargo, si quiero que la base de datos para regular los valores posibles, yo uso una relación de tabla. Yo mucho no les gusta usar enum en el nivel de base de datos, aquí un artículo en la razón: komlenic.com/244/8-reasons-why-mysqls-enum-data-type-is-evil
    • ¿Qué pasa si usted necesita para realizar la lógica en función de un valor? Como, por ejemplo, si alguien se eligió a la «CELDA», a continuación, un nuevo desplegable aparecerá con Android/iOS selecciones, por lo tanto es necesario hacer referencia al valor en el código. Estaría usted de la base de esta lógica condicional en el numérico de la clave principal se encuentra en la base de datos?
    • Me gustaría ya sea que se basen en las teclas numéricas, o sobre el nombre en la relación de la tabla. Así que usted puede tener un phone_type tabla con ID y Name columnas. En Laravel me puede hacer referencia a la relación y hacer lógica condicional como if($customer->phoneType->name == 'Cellular') ....
    • Basándose en el nombre es probablemente la peor idea. Yo ya no me gusta «Celular»; yo podría cambiar a «Móvil» o simplemente «Célula» en el camino — que iba a romper todo mi código. De todos modos, agradezco sus sugerencias. Creo que me voy a ir con Config::get ahora mismo, pero voy a seguir lo que usted dijo en la mente.
    • La doctrina (como para la comprobación de la columna de la existencia y avanzadas herramientas de migración) no admite el tipo de ENUMERACIÓN para el esquema de la creación. Que SOLO es una razón suficientemente buena para evitar las enumeraciones si desea utilizar el esquema de plan de clase en laravel.
    • Eh? Yo no estoy usando Doctrina, estoy usando Laravel. Ctrl+F ->enum. Y es que no se como no podía raw a su alrededor. Yo no creo en hacer trabajos inferiores porque mi marco no lo permite.
    • Laravel es alimentado por symfony symfony es alimentado por la doctrina para la gestión de bases de datos.
    • desplácese hacia abajo en la página que enlaza a encontrar Note: Modifying any column in a table that also has a column of type enum is not currently supported. esta excepción es lanzada por la Doctrina dbal.
    • Laravel utiliza la Doctrina DBAL clases, sí, pero no el ORM. Laravel la propia Elocuente ORM en realidad no admite la enum tipo de columna (no sólo el cambio de nombre, como usted ha señalado). Sin, estoy, obviamente, completamente de acuerdo en que es bueno para evitar la enum tipo de columna de todos modos. =)
    • Bien…yo solo se encontró con el problema de añadir un valor a un enum existentes, y como se advirtió, Laravel maneja miserablemente. Solo los errores de salida. Tenía que escribir algunas primas SQL para actualizar las columnas.
    • gracias por este artículo muy completo éxito
    • El artículo que el enlace no es sobre el no uso de las enumeraciones (a pesar del título), se trata de no misel uso de ellos. El autor aclara esto en los comentarios, también.
    • Mientras estuve de acuerdo en que tener una tabla para los valores, creo que no es correcta: tipos de columna debe reflejar la columna de valores posibles, así como varchar y entero mantenga secuencias de caracteres y números enteros, una enumeración columna puede contener un conjunto predefinido de valores.
    • los tipos de columna debe reflejar el tipo de los valores posibles, no el rango de valores. enum tipos de columna va a meter en problemas.

  2. 56

    No estoy de acuerdo con el aceptado respuesta aquí. Siento que las enumeraciones pueden ser muy útiles para este tipo de cosas. Yo prefiero tratar de las enumeraciones como tipos, e implementar los métodos que usted necesita en la Enumeración de la clase base para darle la funcionalidad que usted necesita, tales como conseguir un diccionario.

    Mi simple ejemplo a continuación:

    abstract class PhoneType extends Enum {
        const Cell = "Cellular";
        const Home = "Home";
        const Work = "Work";
    }
    
    abstract class Enum {
        static function getKeys(){
            $class = new ReflectionClass(get_called_class());
            return array_keys($class->getConstants());
        }
    }

    Ejemplo de uso:

    PhoneType::getKeys();

    Ver PHP y Enumeraciones para obtener más detalles y un análisis más en profundidad de ejemplo.

    • Un buen caso de uso para el enum es el género. Por lo general, sólo se pueden tratar con hombres, mujeres o no especificado. No hay ningún punto en una tabla extra como estos tres valores cubrir todos los casos posibles. Por supuesto, podría tratarse de un caso de uso para el género más designaciones para determinados proyectos, pero que es la excepción.
    • Aún puede ser mejor para cambiar su enumeraciones a tinyint y, a continuación, simplemente el mapa cada una constante para un número entero! De esa manera siempre se puede añadir un cuarto de teléfono (que es probable que suceda). Un comando ALTER table es caro y no vale la pena arriesgar. Ademã ¡s, algunos marcos como doctrina no incluso el apoyo de Enum para el esquema de la creación.
  3. 10

    Edificio en @Banfords respuesta, con PHP7 constantes pueden ahora ser matrices:

    class User extends Authenticatable
    {
        /**
         * The possible genders a user can be.
         */
        const GENDER = [
            'Male',
            'Female',
            'Unspecified'
        ];
    
    ...
    • se te olvida mencionar que nunca se debe usar de ellos para las tablas de búsqueda.
  4. 7

    Además a @Banford la respuesta:

    Recientemente he creado un paquete que hace que trabajar con las enumeraciones en Laravel mucho más agradable. Es una combinación de varias de las implementaciones que había encontrado mientras investigaba cómo hacer la misma cosa (por lo tanto, ¿por qué estoy aquí).

    https://github.com/BenSampo/laravel-enum

    En este caso, se podría hacer algo como lo siguiente:

    final class PhoneTypes extends Enum
    {
        const Cellular = 0;
        const Work = 1;
        const Home = 2;
    }

    Los valores pueden ser accedidos usando:

    PhoneTypes::Work //1

    Yo recomiendo siempre la configuración de los valores de los números enteros y posteriormente almacenarlos en la base de datos como enteros.

    La base de la Enumeración de clase tiene métodos para obtener todas las claves y valores de las matrices. El paquete también cuenta con un par de otros beneficios que pueden ser útiles en este caso, tales como la validación, de modo que un usuario no pueda agregar un inexistente valor a la base de datos.

    También hay un generador, el cual es bastante útil.

    Espero que esto viene de utilidad para alguien.

    • Bien, pero ¿cómo es esto específicos para Laravel? Se parece a muchas de las otras php-enumeración de las implementaciones.
    • La enumeración de implementación es bastante genérico, tienes razón. La Laravel detalles están en el generador y la validación.
  5. 4

    Sólo había problema similar, para mí Elocuente Accesores y modificadores funcionado a la perfección. Para esta pregunta iría como:

    namespace App;
    
    use Illuminate\Database\Eloquent\Model;
    
    class Customer extends Model
    {
        /**
        * @var array
        */
        protected $phoneTypes = [
            'Cellular',
            'Home',
            'Work'
        ];
    
       /**
        * @param int $value
        * @return string|null
        */
        public function getPhoneTypeAttribute($value)
        {
            return Arr::get($this->phoneTypes, $value);
        }
    }

    Por favor, tenga en cuenta que en la base de datos debe guardar valores numéricos, en donde 0 es la célula, 1 en casa y 2 es el trabajo. En segundo lugar, sería aconsejable usar las traducciones aquí en lugar de la propiedad protegida.

  6. 2

    Usted no debe usar enum en todo.

    El oficial de Laravel 5.1 documentación estados:

    Nota: cambiar el nombre de las columnas en una tabla con una columna enum no es compatible actualmente.

    Que sucede cuando usted tiene un enum columna de la tabla de base de datos. Si usted está tratando de rename otro columna, o cambiar otro columna a nullable, el error aparecerá. Es un problema con Doctrine\DBAL.

    Desconocido tipo de base de datos enum solicitado

    Incluso con laravel 5.8, el problema no está resuelto.

    Tengo que añadir que va a tener el mismo problema cuando la adición de opciones disponibles en enum columna de la declaración.

    Me lleva a la conclusión de que debe utilizar enum con cuidado. o incluso Usted no debe usar enum en todo.

    Aquí es un ejemplo de lo difícil que sería la adición de opciones disponibles en enum columna de la declaración de

    decir que tienes este:

    Schema::create('blogs', function (Blueprint $table) {
        $table->enum('type', [BlogType::KEY_PAYMENTS]);
        $table->index(['type', 'created_at']);
    ...

    y necesita realizar más tipos disponibles

    public function up(): void
    {
        Schema::table('blogs', function (Blueprint $table) {
            $table->dropIndex(['type', 'created_at']);
            $table->enum('type_tmp', [
                BlogType::KEY_PAYMENTS,
                BlogType::KEY_CATS,
                BlogType::KEY_DOGS,
            ])->after('type');
        });
    
        DB::statement('update `blogs` as te set te.`type_tmp` = te.`type` ');
    
        Schema::table('blogs', function (Blueprint $table) {
            $table->dropColumn('type');
        });
    
        Schema::table('blogs', function (Blueprint $table) {
            $table->enum('type', [
                BlogType::KEY_PAYMENTS,
                BlogType::KEY_CATS,
                BlogType::KEY_DOGS,
            ])->after('type_tmp');
        });
    
        DB::statement('update `blogs` as te set te.`type` = te.`type_tmp` ');
    
        Schema::table('blogs', function (Blueprint $table) {
            $table->dropColumn('type_tmp');
            $table->index(['type', 'created_at']);
        });
    }

Dejar respuesta

Please enter your comment!
Please enter your name here