Passer au contenu principal

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.
Avant d’utiliser Eloquent, configurez la connexion dans config/database.php. Par défaut, les variables DB_* du .env sont utilisées.

Créer un modèle

Utilisez la commande Artisan make:model.
php artisan make:model Post
Pour créer aussi une migration, utilisez -m.
php artisan make:model Post -m
Le modèle est créé dans app/Models.
<?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èleTable
Postposts
Userusers
AirTrafficControllerair_traffic_controllers
Si le nom ne suit pas cette convention, précisez $table explicitement.
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.
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.
class Post extends Model
{
    protected $fillable = [
        'user_id',
        'title',
        'body',
        'published',
    ];
}

guarded

À l’inverse, $guarded indique les colonnes interdites.
class Post extends Model
{
    // Seule la clé primaire est protégée, le reste est autorisé
    protected $guarded = ['id'];
}
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.

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.

CRUD de base

Lecture (Read)

Récupérer tous les enregistrements.
use App\Models\Post;

$posts = Post::all();
Avec conditions.
// 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).
$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.
$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.
$post = Post::find(1);
$post->title = 'Titre mis à jour';
$post->save();
update met à jour plusieurs colonnes en un appel.
Post::find(1)->update([
    'title' => 'Titre mis à jour',
    'published' => true,
]);
Mise à jour en masse selon un critère.
Post::where('published', false)->update(['published' => true]);

Suppression (Delete)

$post = Post::find(1);
$post->delete();
Suppression directe par ID.
Post::destroy(1);

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

Méthodes de requête de base

MéthodeDescription
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

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');
    }
}
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).

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.

Prochaines étapes

Migrations

Revoyez la création des tables utilisées par Eloquent via les migrations.
Dernière modification le 13 juillet 2026