🎃 12 meses por 75 €

El plan anual a mitad de precio hasta el 31 de octubre.

Aprovechar la oferta

🎃 Halloween: 12 meses por 75 €

Plan anual a mitad de precio, para altas y renovaciones. Solo hasta el 31 de octubre.
Aprovechar la oferta
Saltar al contenido
Curso Actualizar un proyecto de Laravel 11 a Laravel 12
05/09 La actualización a Laravel 12 Larastan 3 en los modelos: genéricos en las relaciones y parseModelCastsMethod
Tu lectura Quedan 17 min
Lección 5 de 9 · La actualización a Laravel 12

Larastan 3 en los modelos: genéricos en las relaciones y parseModelCastsMethod

17 min de lectura Laravel 12

Hola, bienvenido. En esta lección vamos a poner los modelos al día para Larastan 3, que cambia 2 cosas respecto a Larastan 2. La primera son las relaciones: Larastan 3 ya no deduce qué modelo devuelve cada una leyendo el cuerpo del método, así que hay que escribirlo en su PHPDoc, con genéricos. La segunda es al revés, una PHPDoc que sobra: la del método casts(), que necesitaba Larastan 2 y que Larastan 3 puede sustituir leyendo directamente el array que devuelve el método.

Partimos de la lección anterior: Larastan 3 instalado y 7 errores en el análisis, con los tests en verde. Al terminar, el análisis estará en verde y los modelos tendrán la forma que espera Larastan 3.

Las relaciones y los casts, de Larastan 2 a Larastan 3

Esta tabla resume qué hacía Larastan 2 con los modelos y qué hace Larastan 3, y más abajo tienes cada fila resuelta en el proyecto:

Qué Larastan 2 Larastan 3
Relación declarada como public function replies(): HasMany Lee el cuerpo, encuentra hasMany(TicketReply::class) y deduce que devuelve TicketReply No lee el cuerpo: sin genéricos, la relación devuelve un Model cualquiera
Cómo se anota la relación No hace falta @return HasMany<TicketReply, $this>
Segundo genérico de la relación Se llamaba TChildModel Se llama TDeclaringModel: el modelo que declara la relación
Casts en el método casts() Solo los entiende con una PHPDoc @return array{...} que copia el array Con parseModelCastsMethod: true, lee el array del cuerpo del método

En una relación anotada con genéricos, el primero es el modelo relacionado, el que devuelve la relación, y el segundo es el modelo que la declara. Para el segundo se escribe $this y no Ticket, porque así, si otra clase hereda de Ticket, la relación sabe que la declara la clase hija. Las clases de relaciones de Laravel admiten este segundo genérico desde la versión 11.15, y es lo que nos hacía falta en los 5 errores de las acciones de la lección anterior: con HasMany<Ticket, $this> en User::tickets(), Larastan sabe que $customer->tickets()->create() devuelve un Ticket.

¿Por qué Larastan 3 dejó de leer el cuerpo de los métodos? Según su guía de actualización, porque era lento, ya que obligaba a analizar el archivo del modelo, y difícil de mantener. Ahora la información está en la firma del método, que es donde la buscan PHPStan y los editores. Además, PHPStan exige esos genéricos a partir del nivel 6, el que informa de los tipos que faltan, así que anotarlos ahora deja el proyecto preparado para subir de nivel cuando haga falta.

Lo que queda de esta lección
  1. 02AddGenericReturnTypeToRelationsRector
  2. 03parseModelCastsMethod: los casts sin PHPDoc
  3. 04Cuándo una baseline es aceptable y cuándo no
  4. 05composer qa en verde y el commit
Sigue leyendo con tu suscripción El curso completo, con el certificado y el foro, está incluido en la suscripción. Ver los planes