Migraciones en Laravel 11: columnas modificadas con change() y tipos float
Hola, bienvenido. En esta lección vamos a resolver los 2 cambios de la guía de Laravel 11 que afectan a las migraciones del proyecto, los 2 marcados como de impacto alto. En Laravel 11, una migración que modifica una columna con change() pierde los modificadores que no repite, como el valor por defecto, y float() ya no admite el total de dígitos y los decimales, solo la precisión.
Uno de los 2 lo señala Larastan desde la lección 5. El otro no lo detecta nada: ni los tests, ni Larastan, ni el proyecto en marcha. Por eso, antes de corregirlo, vamos a escribir un test que lo haga visible, para que nos avise la próxima vez que una migración cambie el esquema sin querer.
Los 2 cambios que afectan al proyecto
El primero es change(). En Laravel 10, modificar una columna en una migración necesitaba doctrine/dbal: Doctrine leía la definición actual de la columna, le aplicaba los cambios y conservaba el resto de sus modificadores. En la lección 5 quitamos doctrine/dbal, porque Laravel 11 modifica las columnas por su cuenta, y lo hace de otra forma: la columna queda exactamente como la describe la migración, y cualquier modificador que no se repita se pierde. Lo dice así la guía oficial (se abre en una pestaña nueva): hay que incluir explícitamente todos los modificadores que queramos conservar, aunque los añadiera una migración anterior.
Nuestro proyecto tiene ese caso. La migración create_tickets_table crea la columna priority con default('normal'), y meses después make_priority_nullable_on_tickets_table la hace opcional con ->nullable()->change(), para poder guardar tickets sin clasificar, como los que abre el webhook del correo, sin repetir el default.
El segundo es float(). En Laravel 10, float('estimated_hours', 8, 2) recibía el total de dígitos y los decimales. En Laravel 11, float() solo admite la precisión, que decide si la columna se guarda en 4 o en 8 bytes, y para un número con un total de dígitos y unos decimales fijos está decimal().
Vamos a ver cómo están ahora esas 2 columnas en la base de datos de desarrollo, que creamos en la lección 1 con Laravel 10:
priority es opcional y tiene normal como valor por defecto, y estimated_hours es un double(8,2). Es lo que crearon las migraciones con Laravel 10, y es lo que tiene la base de datos de producción. Actualizar a Laravel 11 no cambia ni una columna de una base de datos que ya existe, porque esas migraciones ya se ejecutaron y no se vuelven a ejecutar. El problema aparece, como con la migración de Spatie en la lección 6, en cualquier base de datos que se cree desde cero a partir de ahora.
- 02Un test para el esquema de tickets
- 03"Failed asserting that null is identical to 'normal'."
- 04"Blueprint::float() invoked with 3 parameters, 1-2 required"
- 05Producción, las migraciones ya ejecutadas y schema:dump