informatica:programacion:php:cursos:laravel_8:20250529
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:programacion:php:cursos:laravel_8:20250529 [2023/05/29 13:11] – tempwin | informatica:programacion:php:cursos:laravel_8:20250529 [2023/05/29 14:59] (actual) – tempwin | ||
|---|---|---|---|
| Línea 18: | Línea 18: | ||
| Creará también los métodos para hacer un CRUD. | Creará también los métodos para hacer un CRUD. | ||
| + | |||
| + | En base de datos, aunque nuestro modelo sea singular, Laravel crea la base de datos en plural. | ||
| + | |||
| + | '' | ||
| + | |||
| + | Para crear realmente la estructura en base de datos, lanzamos todas las migraciones: | ||
| + | < | ||
| + | php artisan migrate | ||
| + | </ | ||
| + | |||
| + | Echando vistazo a la base de datos, vemos las siguientes tablas: | ||
| + | |||
| + | * **failed_jobs**: | ||
| + | * **migrations**: | ||
| + | * **password_resets** | ||
| + | * **personal_access_tokens** | ||
| + | * **products** | ||
| + | * **users** | ||
| + | |||
| + | Si queremos forzar a lanzar todas las migraciones: | ||
| + | |||
| + | < | ||
| + | php artisan migra:fresh | ||
| + | </ | ||
| + | |||
| + | <WRAP center round important 60%> | ||
| + | No usar ese comando en producción porque se borrará la base de datos. | ||
| + | </ | ||
| + | |||
| + | |||
| + | Nuevo fichero de migración: | ||
| + | |||
| + | < | ||
| + | php artisan make: | ||
| + | </ | ||
| + | |||
| + | Añadimos un campo nuevo a la tabla " | ||
| + | |||
| + | < | ||
| + | php artisan migrate | ||
| + | </ | ||
| + | |||
| + | Laravel solo ejecutará la nueva migración (porque no está en la tabla **migrations**) | ||
| + | |||
| + | |||
| + | |||
| + | En '' | ||
| + | |||
| + | <code php> | ||
| + | run() { | ||
| + | Product:: | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | php artisan db:seed | ||
| + | </ | ||
| + | |||
| + | Tendremos el registro nuevo en tabla **products**. | ||
| + | |||
| + | En '' | ||
| + | |||
| + | Para tener variedad en los datos que se vayan a meter: | ||
| + | |||
| + | <code php> | ||
| + | public function definition() { | ||
| + | return [ | ||
| + | ' | ||
| + | ' | ||
| + | ]; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | * [[https:// | ||
| + | |||
| + | Modificaríamos ahora '' | ||
| + | |||
| + | <code php> | ||
| + | // ... | ||
| + | Product:: | ||
| + | </ | ||
| + | |||
| + | Como no indicamos nada por argumento a '' | ||
| + | |||
| + | Limpieza: | ||
| + | |||
| + | < | ||
| + | php artisan migrate: | ||
| + | </ | ||
| + | |||
| + | Borra la base de datos, la vuelve a crear y luego la rellena de datos. | ||
| + | |||
| + | Vamos con las rutas. Para poder verlas: | ||
| + | |||
| + | < | ||
| + | php artisan route:list | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | <code php> | ||
| + | public function index() { | ||
| + | return view (" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Creamos la vista: | ||
| + | |||
| + | '' | ||
| + | |||
| + | < | ||
| + | < | ||
| + | <ul> | ||
| + | < | ||
| + | < | ||
| + | </ul> | ||
| + | </ | ||
| + | |||
| + | Ahora podemos ir a http:// | ||
| + | |||
| + | Para pasarle lo que hay en base de datos: | ||
| + | |||
| + | <code php> | ||
| + | public function index() { | ||
| + | |||
| + | // Cogemos todos los productos | ||
| + | $products = Product:: | ||
| + | return view (" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | En la vista: | ||
| + | |||
| + | <code html> | ||
| + | < | ||
| + | <ul> | ||
| + | @foreach($productsList as $product) | ||
| + | < | ||
| + | < | ||
| + | @endforeach | ||
| + | </ul> | ||
| + | </ | ||
| + | |||
| + | **Eloquent** es el ORM que utiliza Laravel. //Object Relational Mapping//. AL profe le gusta más el que usa Symfony: Doctrine. | ||
| + | |||
| + | El modelo Producto y el modelo de datos no tendría que ser lo mismo. Laravel lo junta. Veremos más adelante cómo separarlo. | ||
| + | |||
| + | <code php> | ||
| + | public function index() { | ||
| + | |||
| + | // Cogemos todos los productos | ||
| + | $products = Product:: | ||
| + | | ||
| + | // Para visualizar el contenido y no continuar luego: | ||
| + | dd($products); | ||
| + | return view (" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Vamos con el '' | ||
| + | |||
| + | <code php> | ||
| + | public function create() { | ||
| + | |||
| + | // Cogemos todos los productos | ||
| + | $products = Product:: | ||
| + | | ||
| + | // Para visualizar el contenido y no continuar luego: | ||
| + | dd($products); | ||
| + | return view (" | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Se crea la vista en '' | ||
| + | |||
| + | <code html> | ||
| + | <form action="/ | ||
| + | <input typè=" | ||
| + | <input typè=" | ||
| + | <input typè=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | En el atributo " | ||
| + | |||
| + | Ese formulario irá a | ||
| + | |||
| + | |||
| + | <code php> | ||
| + | public function store(StoreProductRequest $request) { | ||
| + | dd($request); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Al enviar formulario nos saldrá el error 419 page expired se debe al CSRF (Cross Site Request Forgery). Lo arreglamos con: | ||
| + | |||
| + | <code html> | ||
| + | <form action="/ | ||
| + | @csrf | ||
| + | <input typè=" | ||
| + | <input typè=" | ||
| + | <input typè=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Ahora el error cambiará a 403 - non authorized. Miramos '' | ||
| + | |||
| + | Modificamos el '' | ||
| + | |||
| + | <code php> | ||
| + | public function store(StoreProductRequest $request) { | ||
| + | Product:: | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Si ahora volvemos a enviar el formulario, tendremos otro error relacionado con el token. Laravel por seguridad no permite meter de todo. | ||
| + | |||
| + | Solucionamos en el modelo '' | ||
| + | |||
| + | <code php> | ||
| + | use HasFactory; | ||
| + | | ||
| + | protected $fillable = [' | ||
| + | </ | ||
| + | |||
| + | Seguimos modificando la vista: | ||
| + | |||
| + | <code html> | ||
| + | <form action="/ | ||
| + | @csrf | ||
| + | <input type=" | ||
| + | <input type=" | ||
| + | <input type=" | ||
| + | <input type=" | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Ignorará el campo ID porque no está en el '' | ||
| + | |||
| + | Nos mandan hacer una tarea usando TDD para | ||
| + | |||
| + | * Crear modelo: | ||
| + | * Que el modelo esté en base de datos | ||
| + | * Formulario creación | ||
| + | |||
| + | Uno de los primeros indicadores que dice que un test no es unitario es que conecte con base de datos. Sería un test de integración. | ||
| + | |||
| + | **No testeamos código que no sea nuestro**. | ||
| + | |||
| + | Para saber qué testeamos tenemos que pensar primero en qué necesitamos. El test tiene que llevar a un diseño concreto. | ||
| + | |||
| + | No probamos datos, solo comportamientos. Por ejemplo, comprobar si existen ciertos campos. | ||
| + | |||
| + | Tests unitarios: | ||
| + | |||
| + | * Un test unitario no habla con servicios externos (la base de datos es un servicio externo, el reloj del sistema es también externo) | ||
| + | |||
informatica/programacion/php/cursos/laravel_8/20250529.1685358660.txt.gz · Última modificación: por tempwin
