> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Introduzione a Eloquent

> Come manipolare i dati del database usando l'ORM "Eloquent" di Laravel.

## Cos'è Eloquent ORM

Laravel include Eloquent, un Object Relational Mapper (ORM).
Eloquent semplifica l'interazione con il database e implementa il pattern **ActiveRecord**.

Con Eloquent prepari una classe "modello" corrispondente a ciascuna tabella del database.
Tramite il modello puoi recuperare, inserire, aggiornare ed eliminare i record.

<Info>
  Prima di usare Eloquent, configura la connessione al database in `config/database.php`.
  Per impostazione predefinita vengono usate le impostazioni `DB_*` del file `.env`.
</Info>

## Creazione di un modello

Con il comando Artisan `make:model` generi un nuovo modello.

```shell theme={null}
php artisan make:model Post
```

Per crearlo insieme alla migration usa l'opzione `-m`.

```shell theme={null}
php artisan make:model Post -m
```

I modelli vengono creati nella directory `app/Models`.

```php theme={null}
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    // ...
}
```

## Corrispondenza tra modello e tabella

Eloquent deduce automaticamente il nome della tabella dal nome della classe.
Il nome della tabella è la forma plurale in snake\_case del nome della classe.

| Nome del modello       | Nome della tabella        |
| ---------------------- | ------------------------- |
| `Post`                 | `posts`                   |
| `User`                 | `users`                   |
| `AirTrafficController` | `air_traffic_controllers` |

Se il nome della tabella non segue la convenzione, indicalo esplicitamente con la proprietà `$table`.

```php theme={null}
class Post extends Model
{
    protected $table = 'blog_posts';
}
```

### Timestamp

Eloquent gestisce automaticamente le colonne `created_at` e `updated_at` di default.
Se nella migration aggiungi `$table->timestamps()`, i valori vengono impostati automaticamente al salvataggio e all'aggiornamento.

Per disabilitare la gestione automatica imposta `$timestamps` a `false`.

```php theme={null}
class Post extends Model
{
    public $timestamps = false;
}
```

## Protezione da mass assignment

Quando salvi dati in blocco con Eloquent è necessaria la configurazione della protezione da mass assignment.

### fillable

Con la proprietà `$fillable` indichi le colonne che accettano assegnazione.

```php theme={null}
class Post extends Model
{
    protected $fillable = [
        'user_id',
        'title',
        'body',
        'published',
    ];
}
```

### guarded

Per indicare le colonne da vietare all'assegnazione usa `$guarded`.

```php theme={null}
class Post extends Model
{
    // Protegge solo la chiave primaria, consente tutto il resto
    protected $guarded = ['id'];
}
```

<Warning>
  Con `$guarded` come array vuoto consenti l'assegnazione a tutte le colonne.
  Se passi direttamente input utente, c'è il rischio che colonne non previste vengano sovrascritte, quindi è consigliato indicare esplicitamente le colonne consentite con `$fillable`.
</Warning>

## Flusso di esecuzione delle query Eloquent

Ecco come una query come `User::where()->get()` viene eseguita internamente.

```mermaid theme={null}
flowchart LR
    A["User::where('active', true)"] --> B["Costruzione del query builder"]
    B --> C["Chiamata di ->get()"]
    C --> D["Generazione dell'SQL"]
    D --> E["Esecuzione sul database"]
    E --> F["Conversione dei risultati in modelli Eloquent"]
    F --> G["Restituzione come Collection"]
```

## Operazioni CRUD di base

### Recuperare record (Read)

Recupera tutti i record.

```php theme={null}
use App\Models\Post;

$posts = Post::all();
```

Recupera con condizioni.

```php theme={null}
// Recupera i post con published a true
$publishedPosts = Post::where('published', true)->get();

// Recupera il primo
$post = Post::where('published', true)->first();

// Recupera per ID
$post = Post::find(1);

// Restituisce 404 se non trovato
$post = Post::findOrFail(1);
```

### Creare record (Create)

Con il metodo `create` inserisci un record (serve la configurazione di `$fillable`).

```php theme={null}
$post = Post::create([
    'title' => 'Il mio primo post',
    'body' => 'Laravel è un framework fantastico.',
    'published' => true,
]);
```

Puoi anche creare l'istanza e assegnare i valori singolarmente.

```php theme={null}
$post = new Post;
$post->title = 'Il mio primo post';
$post->body = 'Laravel è un framework fantastico.';
$post->save();
```

### Aggiornare record (Update)

Recupera un modello, modifica i valori e chiama `save` per aggiornare.

```php theme={null}
$post = Post::find(1);
$post->title = 'Titolo aggiornato';
$post->save();
```

Con il metodo `update` aggiorni più colonne insieme.

```php theme={null}
Post::find(1)->update([
    'title' => 'Titolo aggiornato',
    'published' => true,
]);
```

Puoi anche aggiornare in blocco più record che soddisfano una condizione.

```php theme={null}
Post::where('published', false)->update(['published' => true]);
```

### Eliminare record (Delete)

Con il metodo `delete` elimini un record.

```php theme={null}
$post = Post::find(1);
$post->delete();
```

Puoi eliminare direttamente specificando l'ID.

```php theme={null}
Post::destroy(1);

// Elimina più ID insieme
Post::destroy([1, 2, 3]);
```

## Metodi di query di base

| Metodo                                       | Descrizione                                         |
| -------------------------------------------- | --------------------------------------------------- |
| `Post::all()`                                | Recupera tutti i record                             |
| `Post::find($id)`                            | Recupera per ID (restituisce `null` se non trovato) |
| `Post::findOrFail($id)`                      | Recupera per ID (restituisce 404 se non trovato)    |
| `Post::where('column', 'value')->get()`      | Recupera i record che soddisfano la condizione      |
| `Post::where('column', 'value')->first()`    | Recupera il primo record che soddisfa la condizione |
| `Post::where('column', 'value')->count()`    | Conta i record che soddisfano la condizione         |
| `Post::orderBy('created_at', 'desc')->get()` | Recupera specificando l'ordinamento                 |
| `Post::latest()->get()`                      | Recupera in ordine decrescente per `created_at`     |
| `Post::limit(10)->get()`                     | Recupera limitando il numero                        |

## Esempio pratico: manipolazione dei dati con il modello Post

Esempio di controller che manipola la tabella `posts` creata con la migration.

```php theme={null}
<?php

namespace App\Http\Controllers;

use App\Models\Post;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class PostController extends Controller
{
    // Mostra l'elenco dei post
    public function index(): View
    {
        $posts = Post::where('published', true)
            ->latest()
            ->get();

        return view('posts.index', ['posts' => $posts]);
    }

    // Crea un post
    public function store(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'body' => ['required', 'string'],
            'published' => ['boolean'],
        ]);

        Post::create([
            ...$validated,
            'user_id' => $request->user()->id,
        ]);

        return redirect('/posts');
    }

    // Aggiorna un post
    public function update(Request $request, Post $post): RedirectResponse
    {
        $validated = $request->validate([
            'title' => ['required', 'string', 'max:255'],
            'body' => ['required', 'string'],
        ]);

        $post->update($validated);

        return redirect('/posts');
    }

    // Elimina un post
    public function destroy(Post $post): RedirectResponse
    {
        $post->delete();

        return redirect('/posts');
    }
}
```

<Tip>
  Scrivendo `Post $post` come argomento del metodo del controller, Laravel recupera automaticamente il modello dai parametri di route (route model binding).
  Non devi più scrivere manualmente `Post::findOrFail($id)`.
</Tip>

## Ciclo di vita degli eventi del modello

Flusso degli eventi emessi quando chiami `save()`. Gli eventi cambiano in base al fatto che sia una creazione o un aggiornamento, ma `saving` e `saved` vengono emessi in entrambi i casi.

```mermaid theme={null}
flowchart TD
    A["Creazione di una nuova istanza"] --> B{"save()"}
    B --> I["Evento saving"]
    I -->|"Creazione"| C["Evento creating"]
    C --> D["Esecuzione INSERT"]
    D --> E["Evento created"]
    I -->|"Aggiornamento"| F["Evento updating"]
    F --> G["Esecuzione UPDATE"]
    G --> H["Evento updated"]
    E --> J["Evento saved"]
    H --> J
```

## Prossimi passi

<Card title="Migration" icon="table" href="/it/migrations">
  Rivedi come creare con le migration le tabelle usate da Eloquent.
</Card>


## Related topics

- [Introduzione alle relazioni Eloquent](/it/eloquent-relationships.md)
- [Collezioni Eloquent](/it/eloquent-collections.md)
- [Serializzazione Eloquent](/it/eloquent-serialization.md)
- [Introduzione all'autenticazione](/it/authentication.md)
- [Eloquent Factory](/it/eloquent-factories.md)
