====== Curso Laravel 8.0 clase 29/05/2023 ====== Notas sobre la clase del 29/05/2023 del curso [[informatica:programacion:php:cursos:laravel_8|Curso de Laravel 8.0]] Resumen semana pasada: * Tests unitarios * Estructura de Laravel * MVC LAravel se lleva muy bien con Vue (y quizás con React). Laravel no quiere jQuery Recordamos la creación del modelo: php artisan make:model Product -a 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. ''database/migrations/....create_products_table.php'' 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**: colas de tareas. Tareas que se ejecutan de manera asíncrona. Envío de e-mails, por ejemplo. Aquí se guardarán las tareas que no han terminado correctamente. * **migrations**: ficheros de migraciones. Los que aparezcan, Laravel no los ejecutará más. * **password_resets** * **personal_access_tokens** * **products** * **users** Si queremos forzar a lanzar todas las migraciones: php artisan migra:fresh No usar ese comando en producción porque se borrará la base de datos. Nuevo fichero de migración: php artisan make:migration adds_description_to_products Añadimos un campo nuevo a la tabla "products" php artisan migrate Laravel solo ejecutará la nueva migración (porque no está en la tabla **migrations**) En ''database/seeders/DatabaseSeeder.php'' vamos a generar datos: run() { Product::factory(['name' => 'tesla 5', 'description' => 'coche que mola'])->create(); } php artisan db:seed Tendremos el registro nuevo en tabla **products**. En ''database/factories/ProductFactory.php'' Para tener variedad en los datos que se vayan a meter: public function definition() { return [ 'name' => $this->faker->name(), 'description' => $this->faker-text() ]; } * [[https://fakerphp.github.io/|Biblioteca Laravel Faker]] Modificaríamos ahora ''DatabaseSeeder.php'': // ... Product::factory(100)->create(); Como no indicamos nada por argumento a ''create'', tomará lo de la biblioteca Faker. Limpieza: php artisan migrate:fresh -- seed 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 ''app/Http/Controllers/ProeductController.php'' public function index() { return view ("product.index"); // el punto sustituye la barra (/) para evitar incompatibilidades Windows-Linux } Creamos la vista: ''resources/views/products/index.blade.php'':

Listado de productos

Ahora podemos ir a http://localhost/product Para pasarle lo que hay en base de datos: public function index() { // Cogemos todos los productos $products = Product::all(); return view ("product.index", ["productsList" => $products]); } En la vista:

Listado de productos

**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. public function index() { // Cogemos todos los productos $products = Product::all(); // Para visualizar el contenido y no continuar luego: dd($products); return view ("product.index", ["productsList" => $products]); } Vamos con el ''create'', para la creación (no confundir con ''store'' que sería el que almacena): public function create() { // Cogemos todos los productos $products = Product::all(); // Para visualizar el contenido y no continuar luego: dd($products); return view ("product.create", ["productsList" => $products]); } Se crea la vista en ''resources/views/products/create.blade.php'':
En el atributo "name" hay que poner el nombre del campo. Ese formulario irá a 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:
@csrf
Ahora el error cambiará a 403 - non authorized. Miramos ''StoreProductRequest.php'' y en el método ''authorize()'' cambiamos el boolean que devuelve (estaba en false, entonces ponemos true). Modificamos el ''store'': public function store(StoreProductRequest $request) { Product::create($request->all()); } 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 ''Product.php'': use HasFactory; protected $fillable = ['name', "description"]; Seguimos modificando la vista:
@csrf
Ignorará el campo ID porque no está en el ''$fillable''. 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)