---
# System prepended metadata

title: 'Laravel [01] (Una app CRUD)'
tags: [' rutes', ' M7', daw, ' Laravel']

---

---
title: Laravel [01] (Una app CRUD)
tags: daw, Laravel, rutes, M7
---

<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Licencia de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />Este obra está bajo una <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">licencia de Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional</a>.

[Enllaç a Hackmk.io](https://hackmd.io/@JdaXaviQ/S1-ILmdxn)
## Laravel [01] (Una app CRUD, quick but not very dirty).
### Creació i configuració del projecte:
```bash=
$ cd /home/isard/src
$ composer create-project laravel/laravel una_app_crud
```
A continuació configurem el nostre Apache2 per a que serveixi la nostra app:
Afegim les següents línies al nostre fitxer de configuració /etc/apache2/apache2.conf
```
<Directory /home/isard/src/una_app_crud/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>
```
I canviem el virtual host per defecte per a que apunti a aquesta nova ubicació:
```
DocumentRoot /home/isard/src/una_app_crud/public
```
Modifiquem un parell de permisos per a que l'usuari www-data pugui accedir còmodament a la nostra aplicació, reiniciem Apache i provem la nostra nova app.
```bash=
$ chmod 751 /home/isard
$ chmod -R 777 /home/isard/src/una_app_crud/storage
$ sudo systemctl restart apache2
$ firefox localhost/
```
![](https://i.imgur.com/HewVTNr.png)

### Generant contingut
Primer de tot anem a preparar la nostra pàgina principal. Heu de reproduir la estructura de carpetes i fitxers següents:
![](https://i.imgur.com/rWD3t3L.png)
```bash=
$ mkdir -p /home/isard/src/una_app_crud/resources/views/layouts/partials
$ cd /home/isard/src/una_app_crud/resources/views/layouts/partials
$ touch footer.blade.php header.blade.php meta.blade.php ../master.blade.php
```

Contigut de meta.blade.php
```php=
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="csrf-token" content="{{ csrf_token() }}">

<title>@yield('pageTitle') | MyCrudApp</title>
```

Contingut de header.blade.php:
```php=
<nav class="navbar">
    <a class="navbar-brand" href="{{asset('/')}}">MyCrudApp</a>
    <div class="nav_container" id="navContainer">
        <ul class="nav_ul">
            <li class="nav-item">
                <a class="nav-link" href="{{asset('/')}}">Home</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#" id="navMenuLink">
                    Menu
                </a>
            </li>
        </ul>
    </div>
</nav>
```
Contingut de footer.blade.php
```php=
<h3>Peu de pàgina</h3>
```
Contingut de master.blade.php
```php=
<!DOCTYPE html>
<html lang="ca">
<head>
    @include('layouts.partials.meta')
    @yield('scripts')
</head>

<body>

@include('layouts.partials.header')

<div class="container">
    @yield('content')
</div>

@include('layouts.partials.footer')

</body>
</html>
```


Contingut de welcome.blade.php:
```php=
@extends('layouts.master')

@section('pageTitle', 'Home')

@section('content')
    <div class="contingut">
        <h1>Hola, tècnics superiors en desenvolupament!</h1>
        <p>Una altra app CRUD, però aquesta feta amb Laravel.</p>

    </div>
@endsection
```
### La persistència de dades.
Com que som a una classe, intentaré ser original i les nostres dades aniran sobre estudiants; de moment tindrem una única taula anomenada estudiants, amb els següents camps:
* id
* nom 
* cognom
* edat
* email

Passes a seguir:
1.- Crear una nova base de dades.
2.- Connectar el nostre projecte Laravel a la nostra base de dades mySQL.
3.- Generar la nostra migració d'estudiants.
4.- Executar la migració.
5.- Crear un model per a la taula estudiants.

#### Creació de la base de dades:
Es possible crear la base de dades directament des de laravel si s'escau, però no ho he considerat adient per la nostra activitat.

```bash=
$ sudo mysql
MariaDB [(none)]> create database laraveldb;
Query OK, 1 row affected (0,002 sec)

MariaDB [(none)]> ALTER DATABASE laraveldb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Query OK, 1 row affected (0,001 sec)

MariaDB [(none)]> create user 'laravel'@'localhost' identified by '1234';
Query OK, 0 rows affected (0,008 sec)

MariaDB [(none)]> grant all privileges on laraveldb.* to 'laravel'@'localhost';
Query OK, 0 rows affected (0,003 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0,002 sec)
```
Ara configurem el fitxer .env per a subministrar-li les credencials de connexió a la base de dades.
```bash=
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=laraveldb
DB_USERNAME=laravel
DB_PASSWORD=1234
```
#### La nostra primera migració.
```bash=
$ cd /home/isard/src/una_app_crud/
$ php artisan make:migration create_estudiants_table

   INFO  Migration [database/migrations/2023_03_26_102803_create_estudiants_table.php] created successfully.
   
```
Aquesta darrera comanda ens hauria d'haver creat un nou fitxer a la carpeta /database/migrations/ amb un nom semblant a: __2023_02_26_102803_create_estudiants_table.php__
Si editem aquest fitxer trobarem dues funcions: up() i down(), aquestes funcions són les encarregades de crear i destruir la taula estudiants quan ho necessitem i les podem editar al nostre gust, per exemple per afegir-hi més camps a la nostra futura nova taula. En el nostre cas, modificarem la funció up() i la deixarem així:
```php=
public function up(): void
    {
        Schema::create('estudiants', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('nom'); 
            $table->string('cognom'); 
            $table->integer('edat'); 
            $table->string('email'); 
            $table->timestamps();
        });
    }
```
Abans de còrrer la nostra primera migració ens hem d'assegurar que tenim instal·lats els connectors adients per a la nostra base de dades:
```bash=
$ sudo apt install php-mdb2-driver-mysql
$ php artisan migrate

   INFO  Preparing database.  

  Creating migration table ......................................... 25ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ............................ 485ms DONE
  2014_10_12_100000_create_password_reset_tokens_table ............. 39ms DONE
  2019_08_19_000000_create_failed_jobs_table ....................... 35ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ........... 125ms DONE
  2023_03_26_103552_create_estudiants_table ........................ 17ms DONE

```

Com poder apreciar a continuació se n'han creat diverses taules relacionades amb el nostre projecte a la base de dades, entre elles la que contindrà la informació dels nostres estudiants:

![](https://i.imgur.com/hsW1Nfq.png)
![](https://i.imgur.com/A2QkkTf.png)
En aquest punt tenim una taula que al haver-se creat sota el control de Laravel, també pot èsser actualitzada des de Laravel mitjançant migracions.

#### El model Estudiant.

Ara ens toca crear el seu model i això o com a mínim la part inicial també li podem delegar a Artisan:
```bash=
$ php artisan make:model Estudiant
```
i ens crearà el fitxer: 'una_app_crud/app/Models/Estudiant.php' que per dins tindrà aquesta pinta:
```php=
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Estudiant extends Model
{
    use HasFactory;
}

```
Modificarem el codi per afegir una propietat que combinada amb Eloquent i Laravel omplir de forma massiva les propietats dels _nostres estudiants_.
```php=
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Estudiant extends Model
{
    use HasFactory;

    protected $fillable = [
        'nom',
        'cognom',
        'edat',
        'email'
    ];
}

```
No us preocupeu gaire si no veieu com utilitzar aquesta propietat ara mateix, quedarà força més clar més endavant amb un exemple més endavant.

### El controlador EstudiantController.
Deixarem aquí el desenvolupament de la persistència dels nostres estudiants i passarem a implementar el controlador associat.
Encarreguen a Artisan que generi el controlador EstudiantController per nosaltres i li passem el paràmetre --resource per a indicar-li que volem implementar el CRUD complert.

```bash=
~/src/una_app_crud$ php artisan make:controller EstudiantController --resource

   INFO  Controller [app/Http/Controllers/EstudiantController.php] created successfully.  

~/src/una_app_crud$ cat ./app/Http/Controllers/EstudiantController.php 
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Estudiant;

class EstudiantController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}

```
:bomb: Boooom! Ens ha generat un controlador amb l'esquelet de les funcions necessàries per realitzar un CRUD complert.
Per a que puguem enllaçar-lo amb el seu model introduirem la següent línia al codi generat del fitxer EstudiantController:
```php=
use App\Models\Estudiant;
```
#### funció index()
És la funció encarregada de retornar el llistat complert de tots els estudiants.
```php=
public function index()
    {
        $estudiants = Estudiant::all();
        return view('estudiants.index', compact('estudiants','estudiants'));
    }
```

#### funció create()
Ens durà a una vista on podrem crear un nou estudiant des de zero.
```php=
public function create()
    {
        return view('estudiants.create');
    }
```
#### funció store()
Desa un nou usuari, per exemple un acabat de crear desprès de cridar a la funció create().
```php=
public function store(Request $request)
    {
        $this->validate($request, [
            'nom' => 'required',
            'cognom' => 'required',
            'edat' => 'required|numeric',
            'email' => 'required|email',
        ]);

        $input = $request->all();

        Estudiant::create($input);

        return redirect()->route('estudiants.index');
    }
```

#### funció show()
Obté un estudiant a partir de la seva id.
```php=
public function show($id)
    {
        $estudiant = Estudiant::findOrFail($id);
        return view('estudiants.show', compact('estudiant','estudiant'));
    }
```

#### funció edit()
De la mateixa forma que show(), obté un estudiant a partir de la seva id, però en aquest cas ens el presenta en un formulari per a poder-lo modificar.
```php=
public function edit($id)
    {
        $estudiant = Estudiant::find($id);
        
        return view('estudiants.edit', compact('estudiant','estudiant'));
    }
```

#### funció update()
Recupera un estudiant de la base de dades, el modifica amb les dades passades com a parámetre i desa les modificacions a la base de dades.
```php=
public function update(Request $request, $id)
    {

        $estudiant = Estudiant::findOrFail($id);

        $this->validate($request, [
            'nom' => 'required',
            'cognom' => 'required',
            'edat' => 'required|numeric',
            'email' => 'required|email',
        ]);

        $input = $request->all();

        $estudiant->fill($input)->save();

        return redirect()->route('estudiants.index');
    }
```

#### funció destroy()
Esborra un estudiant de la base de dades.
```php=
public function destroy($id)
    {
        $estudiant = Estudiant::findOrFail($id);

        $estudiant->delete();
        
        return redirect()->route('estudiants.index');
    }
```
#### Rutes:
Totes aquestes funcions no poden ser executades si no les enllaçem amb el client a través de rutes, per exemple:

> Route::get('/estudiants/index', [EstudiantController::class, 'index']);

Però no serà aquesta la manera en que generarem les nostres rutes per a realitzar el CRUD dels nostres usuaris. Aprofitarem que varem crear el nostre controlador amb el modificador --resource i que el CRUD el fem amb les funcions generades automàticament per Laravel per a utilitzar una ruta especial de Laravel que aten totes les crides CRUD sense haver d'especificar-les una a una. Afegirem la següent línia al fitxer: routes/web.php

> Route::resource('estudiants', '\App\Http\Controllers\EstudiantController');

Un cop arrivats a aquest punt, hariem poder veure les següents rutes si li preguntem a artisan quines rutes té el nostre projecte:
```php=
~/src/una_app_crud$ php artisan route:list

  GET|HEAD        / ................................................................................................................................. 
  POST            _ignition/execute-solution .......................... ignition.executeSolution › Spatie\LaravelIgnition › ExecuteSolutionController
  GET|HEAD        _ignition/health-check ...................................... ignition.healthCheck › Spatie\LaravelIgnition › HealthCheckController
  POST            _ignition/update-config ................................... ignition.updateConfig › Spatie\LaravelIgnition › UpdateConfigController
  GET|HEAD        api/user .......................................................................................................................... 
  GET|HEAD        estudiants ........................................................................... estudiants.index › EstudiantController@index
  POST            estudiants ........................................................................... estudiants.store › EstudiantController@store
  GET|HEAD        estudiants/create .................................................................. estudiants.create › EstudiantController@create
  GET|HEAD        estudiants/{estudiant} ................................................................. estudiants.show › EstudiantController@show
  PUT|PATCH       estudiants/{estudiant} ............................................................. estudiants.update › EstudiantController@update
  DELETE          estudiants/{estudiant} ........................................................... estudiants.destroy › EstudiantController@destroy
  GET|HEAD        estudiants/{estudiant}/edit ............................................................ estudiants.edit › EstudiantController@edit
  GET|HEAD        sanctum/csrf-cookie ............................................. sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show

                                                                                                                                  Showing [13] routes

```
### Vistes.
#### Vista index.
Aquesta vista serà el cor de la nostra aplicació, des d'aquí crearem els enllaços a la resta de funcionalitats.

* Creació del fitxer de la vista
```bash=
$ cd /home/isard/src/una_app_crud/
$ mkdir -p ./resources/views/estudiants
$ touch ./resources/views/estudiants/index.blade.php
```
Omplir el fitxer index.blade.php que acavem de crear amb el següent contingut:
```php=
@extends('layouts.master')

@section('pageTitle', 'Index Estudiants')

@section('content')
    <h1>Index d'estudiants</h1>
    <a href="{{route('estudiants.create')}}">Create New</a>
    <hr/>


    <table class="table">
        <thead>
        <th>Nom</th>
        <th>Cognom</th>
        <th>Edat</th>
        <th>Email</th>
        <th colspan="3">Accions</th>
        </thead>

        <?php $even = FALSE; ?>
        @foreach($estudiants as $estudiant)
            <tr class= <?php echo $even ? '"even_row"' : '"odd_row"'; $even = !$even ?>>
                <td>{{$estudiant->nom}}</td>
                <td>{{$estudiant->cognom}}</td>
                <td>{{$estudiant->edat}}</td>
                <td>{{$estudiant->email}}</td>
                <td>
                    <div>
                        <a href="{{route('estudiants.show', $estudiant->id)}}" >Details</a>
                        <a href="{{route('estudiants.edit', $estudiant->id)}}" >Edit</a>

                        <form class="inline_form" action="{{ route('estudiants.destroy', $estudiant->id) }}" method="POST">
                            <input type="hidden" name="_method" value="DELETE">
                            <input type="hidden" name="_token" value="{{ csrf_token() }}">
                            <button>Delete User</button>
                        </form>
                    </div>

                </td>
            </tr>
        @endforeach
    </table>

@endsection
```

#### Vista create.
En aquesta vista utilitzarem un paquet de Laravel anomenat [Laravel Collective](https://laravelcollective.com/docs/6.x/html) que ens ajudarà a manegar el contigut dels formularis HTML. Per a istal·lar el paquet anirem al directori arrel del nostre projecte i executarem la següent comanda:
```bash=
$ cd /home/isard/src/una_app_crud
$  composer require laravelcollective/html
Info from https://repo.packagist.org: #StandWithUkraine
./composer.json has been updated
Running composer update laravelcollective/html
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
  - Locking laravelcollective/html (v6.4.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Downloading laravelcollective/html (v6.4.0)
  - Installing laravelcollective/html (v6.4.0): Extracting archive
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   INFO  Discovering packages.  

  laravel/sail ......................................................................................................................... DONE
  laravel/sanctum ...................................................................................................................... DONE
  laravel/tinker ....................................................................................................................... DONE
  laravelcollective/html ............................................................................................................... DONE
  nesbot/carbon ........................................................................................................................ DONE
  nunomaduro/collision ................................................................................................................. DONE
  nunomaduro/termwind .................................................................................................................. DONE
  spatie/laravel-ignition .............................................................................................................. DONE

80 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets].  

No security vulnerability advisories found
Using version ^6.4 for laravelcollective/html

$ touch ./resources/views/estudiants/create.blade.php

$ php artisan cache:clear
$ sudo chmod -R 777 storage/
$ composer dump-autoload
```
Contingut de create.blade.php:
```php=
@extends('layouts.master')

@section('pageTitle', 'Create Estudiant')

@section('content')
    <h1>Crea un nou estudiant</h1>

    <hr/>

    <!-- if validation in the controller fails, show the errors -->
    @if ($errors->any())
        <div>
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif

    <!-- Open the form with the store function route. -->
    {{ Form::open(['action' => 'App\Http\Controllers\EstudiantController@store'])}}

    <!-- Include the CRSF token -->
    {{Form::token()}}

    
    <!-- build our form inputs -->
    <div class="form-group">
        {{Form::label('nom', 'Nom')}}
        {{Form::text('nom', '', ['class' => 'form-control'])}}
    </div>

    <div class="form-group">
        {{Form::label('cognom', 'Cognom')}}
        {{Form::text('cognom', '', ['class' => 'form-control'])}}
    </div>

    <div class="form-group">
        {{Form::label('edat', 'Edat')}}
        {{Form::number('edat', '', ['class' => 'form-control'])}}
    </div>

    <div class="form-group">
        {{Form::label('email', 'Adreça email')}}
        {{Form::text('email', '', ['class' => 'form-control'])}}
    </div>
    <!-- build the submission button -->
    {{Form::submit('Crear!', ['class' => 'btn btn-primary'])}}
    {{ Form::close() }}

@endsection
```

#### Vista show.
show.blade.php
```php=
@extends('layouts.master')

@section('pageTitle', 'Detalls Estudiant')

@section('content')
    <h1>Detalls d'estudiant</h1>

    <hr/>

    <dl>
        <dt>Nom</dt>
        <dd>{{$estudiant->nom}}</dd>

        <dt>Cognom</dt>
        <dd>{{$estudiant->cognom}}</dd>

        <dt>Edat</dt>
        <dd>{{$estudiant->edat}}</dd>

        <dt>Email</dt>
        <dd>{{$estudiant->email}}</dd>
    </dl>

    <div>
        <a href="{{route('estudiants.edit', $estudiant->id)}}">Edit</a>

        <form action="{{ route('estudiants.destroy', $estudiant->id) }}" method="POST">
            <input type="hidden" name="_method" value="DELETE">
            <input type="hidden" name="_token" value="{{ csrf_token() }}">
            <button>Delete User</button>
        </form>
    </div>
@endsection
```

#### Vista edit.
edit.blade.php

```php=
@extends('layouts.master')

@section('pageTitle', 'Edit Students Details')

@section('content')

    <h1>Edit Student</h1>

    <hr/>
    <!-- if validation in the controller fails, show the errors -->
    @if ($errors->any())
        <div>
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif

    <!-- Open the form with the store function route. -->
    {{ Form::open(['action' => ['\App\Http\Controllers\EstudiantController@update', $estudiant->id], 'method' => 'PUT']) }}
    <!-- Include the CRSF token -->
    {{Form::token()}}
    <!-- build our form inputs -->
    <div class="form-group">
        {{Form::label('nom', 'Nom')}}
        {{Form::text('nom', $estudiant->nom, ['class' => 'form-control'])}}
    </div>

    <div class="form-group">
        {{Form::label('cognom', 'Cognom')}}
        {{Form::text('cognom', $estudiant->cognom, ['class' => 'form-control'])}}
    </div>

    <div class="form-group">
        {{Form::label('edat', 'Edat')}}
        {{Form::number('edat', $estudiant->edat, ['class' => 'form-control'])}}
    </div>

    <div class="form-group">
        {{Form::label('email', 'Adreça email')}}
        {{Form::text('email', $estudiant->email, ['class' => 'form-control'])}}
    </div>

    {{Form::submit('Actualitza!')}}
    {{ Form::close() }}
    
@endsection
```

### Retocant el menú de navegació.
Ara que ja tenim enllestides les rutes i les vistes associades, podem retocar el menú de navegació per a incloure les noves funcionalitats.
#### Nou contingut de la plantilla parcial header.blade.php
```php=
<nav class="navbar">
    <a class="navbar-brand" href="{{asset('/')}}">MyCrudApp</a>
    <div class="nav_container" id="navContainer">
        <ul class="nav_ul">
            <li class="nav-item">
                <a class="nav-link" href="{{asset('/')}}">Home</a>
            </li>
            <li class="nav-item">
                <a href="{{route('estudiants.index')}}">Index</a>
            </li>
            <li class="nav-item">
                <a href="{{route('estudiants.create')}}">Create</a>
            </li>
        </ul>
    </div>
</nav>
```
### Aplicant estils.
/home/isard/src/una_app_crud/public/css/style.css
```css=
.navbar{
    margin: 1em;
}
.navbar-brand {
    margin: 1em;
    display: block;
}
.nav_container * {
    display: inline;
    
}
.nav_container li {
    background-color: lightsteelblue;
    padding: 0.3em;
    margin: 3px;
    border-radius: 0.3em;
}

.inline_form {
    display: inline;
}

.even_row {
    background-color: cornsilk;
}

.odd_row {
    background-color: azure;
}
```
I així hauria d'haber quedat la pàgina desprès d'aplicar els estils ;)
![](https://i.imgur.com/FiGPbCh.png)

### I si fem també una API?
Com és evident, Laravel no ens permet només crear pàgines web, també podem generar APIs i seguir aprofitant els recursos que ens proporciona el framework.
En un primer pas, oferirem el llistat d'estudiants a la mateixa ruta que la pàgina web, però emprant el prefix /api devant de la ruta original.
![](https://i.imgur.com/awtYTYg.png)

Per aconsseguir que funcioni aquesta ruta, primer hem d'afegir-la al fitxer ./routes/api.php

```php=
Route::get('/estudiants', '\App\Http\Controllers\EstudiantController@index_api');
```
La ruta utilitzarà el controlador pre-existent EstudiantController, però l'haurem d'editar per a afegir-li el mètode index_api:

```php=
    /**
    * Display a listing of the resource.
    */
    public function index()
    {
        $estudiants = Estudiant::all();
        return view('estudiants.index', compact('estudiants','estudiants'));
    }

    public function index_api()
    {
        //  $estudiants = Estudiant::all();
        //  return response()->json($estudiants);
        return Estudiant::all();
    }
```
El codi comentat és més evident, però el codi actiu a banda de ser més compacte il·lustra com Laravel converteix directament a JSON els resultats de consultes Eloquent(ORM) quan les envia com a resposta.
