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

# Introduction à Eloquent

> Comment manipuler les données de la base avec l'ORM Eloquent de Laravel.

## Qu'est-ce qu'Eloquent ORM

Laravel inclut Eloquent, un ORM (object-relational mapper).
Eloquent facilite le dialogue avec la base et implémente le **pattern ActiveRecord**.

Avec Eloquent, vous créez une classe « modèle » pour chaque table de la base.
Le modèle permet de récupérer, insérer, mettre à jour et supprimer des enregistrements.

<Info>
  Avant d'utiliser Eloquent, configurez la connexion dans `config/database.php`.
  Par défaut, les variables `DB_*` du `.env` sont utilisées.
</Info>

## Créer un modèle

Utilisez la commande Artisan `make:model`.

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

Pour créer aussi une migration, utilisez `-m`.

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

Le modèle est créé dans `app/Models`.

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

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

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

## Correspondance modèle / table

Eloquent déduit le nom de la table à partir du nom de classe : snake\_case au pluriel.

| Modèle                 | Table                     |
| ---------------------- | ------------------------- |
| `Post`                 | `posts`                   |
| `User`                 | `users`                   |
| `AirTrafficController` | `air_traffic_controllers` |

Si le nom ne suit pas cette convention, précisez `$table` explicitement.

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

### Timestamps

Par défaut, Eloquent gère automatiquement `created_at` et `updated_at`.
Ajoutez `$table->timestamps()` à la migration pour bénéficier du remplissage automatique lors des enregistrements et mises à jour.

Pour désactiver cette gestion automatique, mettez `$timestamps` à `false`.

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

## Protection contre l'assignation en masse

Pour utiliser les méthodes de création en masse, configurez la protection.

### fillable

Indiquez les colonnes autorisées via `$fillable`.

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

### guarded

À l'inverse, `$guarded` indique les colonnes interdites.

```php theme={null}
class Post extends Model
{
    // Seule la clé primaire est protégée, le reste est autorisé
    protected $guarded = ['id'];
}
```

<Warning>
  Un `$guarded` vide autorise l'assignation de toutes les colonnes.
  Si vous passez directement des données utilisateur, des colonnes non prévues risquent d'être modifiées. Préférez lister explicitement les colonnes autorisées avec `$fillable`.
</Warning>

## Flux d'exécution d'une requête Eloquent

Voici comment une requête telle que `User::where()->get()` est exécutée en interne.

```mermaid theme={null}
flowchart LR
    A["User::where('active', true)"] --> B["Construction du query builder"]
    B --> C["Appel de ->get()"]
    C --> D["Génération du SQL"]
    D --> E["Exécution sur la base"]
    E --> F["Conversion en modèles Eloquent"]
    F --> G["Retour d'une Collection"]
```

## CRUD de base

### Lecture (Read)

Récupérer tous les enregistrements.

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

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

Avec conditions.

```php theme={null}
// Publications publiées
$publishedPosts = Post::where('published', true)->get();

// Premier résultat
$post = Post::where('published', true)->first();

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

// 404 si absent
$post = Post::findOrFail(1);
```

### Création (Create)

`create` insère un enregistrement (nécessite `$fillable`).

```php theme={null}
$post = Post::create([
    'title' => 'Première publication',
    'body' => 'Laravel est un excellent framework.',
    'published' => true,
]);
```

Vous pouvez aussi créer une instance et lui assigner les valeurs.

```php theme={null}
$post = new Post;
$post->title = 'Première publication';
$post->body = 'Laravel est un excellent framework.';
$post->save();
```

### Mise à jour (Update)

Récupérez le modèle, modifiez-le, puis `save`.

```php theme={null}
$post = Post::find(1);
$post->title = 'Titre mis à jour';
$post->save();
```

`update` met à jour plusieurs colonnes en un appel.

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

Mise à jour en masse selon un critère.

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

### Suppression (Delete)

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

Suppression directe par ID.

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

// Plusieurs IDs
Post::destroy([1, 2, 3]);
```

## Méthodes de requête de base

| Méthode                                      | Description                                  |
| -------------------------------------------- | -------------------------------------------- |
| `Post::all()`                                | Tous les enregistrements                     |
| `Post::find($id)`                            | Par ID (`null` si absent)                    |
| `Post::findOrFail($id)`                      | Par ID (404 si absent)                       |
| `Post::where('column', 'value')->get()`      | Enregistrements correspondant à la condition |
| `Post::where('column', 'value')->first()`    | Premier résultat correspondant               |
| `Post::where('column', 'value')->count()`    | Nombre de résultats                          |
| `Post::orderBy('created_at', 'desc')->get()` | Avec tri                                     |
| `Post::latest()->get()`                      | Trie par `created_at` décroissant            |
| `Post::limit(10)->get()`                     | Limite le nombre de résultats                |

## Exemple : contrôleur manipulant le modèle Post

Exemple de contrôleur pour la table `posts` créée par une 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
{
    // Liste des publications
    public function index(): View
    {
        $posts = Post::where('published', true)
            ->latest()
            ->get();

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

    // Création
    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');
    }

    // Mise à jour
    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');
    }

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

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

<Tip>
  Type-hinter `Post $post` dans une méthode de contrôleur active le route model binding : Laravel récupère automatiquement le modèle depuis le paramètre de route.
  Vous n'avez plus besoin d'écrire vous-même `Post::findOrFail($id)`.
</Tip>

## Cycle de vie des événements de modèle

Voici les événements déclenchés lors de `save()`. Ils diffèrent selon création ou mise à jour, mais `saving` et `saved` s'exécutent dans les deux cas.

```mermaid theme={null}
flowchart TD
    A["Création d'une nouvelle instance"] --> B{"save()"}
    B --> I["Événement saving"]
    I -->|"Création"| C["Événement creating"]
    C --> D["Exécution INSERT"]
    D --> E["Événement created"]
    I -->|"Mise à jour"| F["Événement updating"]
    F --> G["Exécution UPDATE"]
    G --> H["Événement updated"]
    E --> J["Événement saved"]
    H --> J
```

## Prochaines étapes

<Card title="Migrations" icon="table" href="/fr/migrations">
  Revoyez la création des tables utilisées par Eloquent via les migrations.
</Card>


## Related topics

- [Introduction aux relations Eloquent](/fr/eloquent-relationships.md)
- [Introduction à l'authentification](/fr/authentication.md)
- [Collections Eloquent](/fr/eloquent-collections.md)
- [Sérialisation Eloquent](/fr/eloquent-serialization.md)
- [Factories Eloquent](/fr/eloquent-factories.md)
