Laravel: Éviter l'erreur "slug déjà pris" lors des mises à jour

Tim
March 20th, 2025
image description

Comment éviter l'erreur "Slug déjà pris" lors de la mise à jour dans Laravel

Vous avez déjà passé des heures à déboguer une erreur de validation qui semble n'avoir aucun sens ? Celle où Laravel refuse de mettre à jour votre article parce que le "slug est déjà utilisé"... par lui-même ? Frustrant, n'est-ce pas ?

Le problème qui donne des migraines

Imaginez la scène : vous développez une application Laravel avec une belle interface d'administration. Votre client modifie le titre d'un article mais laisse le slug inchangé. Au moment de sauvegarder... BOUM ! Message d'erreur : "Le slug est déjà pris".

Mais comment ? C'est son propre slug ! 🤦‍♂️

Ce problème se manifeste quand vous avez une règle de validation comme celle-ci :

php
<?php
'slug' => ['required', 'string', 'unique:articles,slug', 'max:255'],

Le problème ? Cette règle vérifie si le slug existe déjà dans la table, sans tenir compte du fait que c'est peut-être le même enregistrement que vous essayez de mettre à jour.

La solution élégante (et ridiculement simple)

La solution tient en une ligne de code. Oui, UNE SEULE ligne qui vous épargnera des heures de frustration :

php
<?php
Rule::unique('articles', 'slug')->ignore($articleId)

Voici comment l'implémenter dans votre FormRequest :

php
<?php
use Illuminate\Validation\Rule;

public function rules(): array
{
    // Récupérer l'ID depuis le paramètre de route
    $articleId = $this->route('article');

    return [
        'title' => ['required', 'string', 'max:255'],
        'slug' => [
            'required', 
            'string', 
            'max:255',
            // Ignorer l'enregistrement actuel dans la vérification d'unicité
            Rule::unique('articles', 'slug')->ignore($articleId),
        ],
        'content' => ['required', 'string'],
    ];
}

Pourquoi ça fonctionne ?

Cette solution fonctionne parce qu'elle dit à Laravel : "Vérifie si ce slug est unique, mais ignore l'enregistrement qui a cet ID". Simple, efficace, et ça évite à vos utilisateurs de s'arracher les cheveux.

Une petite astuce pour les routes ressources

Si vous utilisez des routes ressources comme celles-ci :

php
<?php
Route::apiResource('articles', ArticleController::class);

Le paramètre de route sera automatiquement la version singulière de votre ressource (ici, 'article'). Vous n'avez donc pas besoin de vous casser la tête avec des noms de paramètres compliqués.

Conclusion : un petit détail qui change tout

Parfois, les solutions les plus simples sont celles qui nous échappent le plus longtemps. Cette petite modification dans vos règles de validation peut faire une énorme différence dans l'expérience utilisateur de votre application.

Alors, la prochaine fois que vous configurez une validation d'unicité dans Laravel, n'oubliez pas la méthode ignore() — votre santé mentale vous en remerciera !