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

# Modèles Pivot personnalisés et chaperone

> Découvrez comment traiter la table intermédiaire d'un belongsToMany comme un modèle Pivot personnalisé, ainsi que l'eager loading automatique introduit par la méthode chaperone ajoutée dans Laravel 13.

## Qu'est-ce qu'un modèle pivot personnalisé

Par défaut, la table intermédiaire d'un [belongsToMany (relation plusieurs-à-plusieurs)](/fr/eloquent-relationships#belongstomany-plusieurs-a-plusieurs) est représentée par une instance brute de `Illuminate\Database\Eloquent\Relations\Pivot`. Si vous souhaitez ajouter des colonnes supplémentaires à la table intermédiaire (date d'approbation, type de rôle, etc.), ou définir des accesseurs, mutateurs ou méthodes personnalisées, vous pouvez créer un modèle personnalisé qui hérite de `Pivot`.

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

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\Pivot;

class RoleUser extends Pivot
{
    protected function casts(): array
    {
        return [
            'approved' => 'boolean',
        ];
    }
}
```

Dans la définition de `belongsToMany`, appelez `using()` pour indiquer à la relation qu'elle doit utiliser ce modèle personnalisé.

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

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Role extends Model
{
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class)
            ->using(RoleUser::class);
    }
}
```

<Info>
  Lorsque vous nommez un modèle pivot personnalisé, il est de convention de le nommer avec les **noms des deux modèles au singulier, dans l'ordre alphabétique** (`RoleUser` et non `UserRole`). Il s'agit cependant d'une simple convention : le nom de classe réel peut être choisi librement.
</Info>

## Choisir les attributs à récupérer avec `as()`

Par défaut, les valeurs de la table intermédiaire sont accessibles via la propriété `pivot`. La méthode `as()` permet de renommer cette propriété.

```php theme={null}
return $this->belongsToMany(Role::class)
    ->using(RoleUser::class)
    ->as('membership')
    ->withTimestamps()
    ->withPivot('approved');
```

```php theme={null}
foreach ($user->roles as $role) {
    echo $role->membership->approved;
    echo $role->membership->created_at;
}
```

## Colonnes supplémentaires et timestamps

Si la table intermédiaire comporte des colonnes supplémentaires comme `approved`, vous devez les inclure explicitement dans le résultat avec `withPivot()`. Pour gérer `created_at` / `updated_at`, appelez `withTimestamps()`.

```php theme={null}
return $this->belongsToMany(Role::class)
    ->using(RoleUser::class)
    ->withPivot('approved')
    ->withTimestamps();
```

<Warning>
  Eloquent ne met automatiquement à jour la colonne `updated_at` de la table intermédiaire que lorsque le modèle pivot est explicitement défini via `using()`. `withTimestamps()` fonctionne aussi avec la classe `Pivot` par défaut, mais préciser un modèle personnalisé avec `using()` vous permet de bénéficier d'événements personnalisés, de casts personnalisés, etc.
</Warning>

## Références inverses depuis le modèle pivot

Vous pouvez librement définir des relations `belongsTo` sur le modèle pivot personnalisé pour remonter vers le modèle déclarant et le modèle lié.

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

namespace App\Models;

use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;

class RoleUser extends Pivot
{
    public function role(): BelongsTo
    {
        return $this->belongsTo(Role::class);
    }

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}
```

Ainsi, même en récupérant un modèle pivot isolément, vous pouvez accéder aux modèles liés via `$roleUser->role` ou `$roleUser->user`. Si vous souhaitez que ces relations soient automatiquement eager-loadées lors de l'exécution de la requête parente, la méthode `chaperone()` présentée ci-dessous est faite pour cela.

## Eager loading automatique avec `chaperone()` (Laravel 13)

Laravel 13 introduit la méthode `chaperone()`, qui permet d'hydrater automatiquement (l'équivalent d'un eager loading) les relations `belongsTo` comme `role()` / `user()` définies sur le modèle pivot, lorsque la requête `belongsToMany` s'exécute.

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

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;

class Role extends Model
{
    public function users(): BelongsToMany
    {
        return $this->belongsToMany(User::class)
            ->using(RoleUser::class)
            ->chaperone();
    }
}
```

Lorsque vous appelez `chaperone()`, Eloquent déduit automatiquement le nom des relations `belongsTo` définies sur le modèle pivot (`RoleUser`). Ainsi, lorsque vous récupérez une collection via `Role::with('users')`, il rattache aux pivots les références vers le modèle déclarant et le modèle lié sans requête supplémentaire.

```php theme={null}
$role = Role::with('users')->first();

foreach ($role->users as $user) {
    // Accès au modèle parent via le pivot sans requête supplémentaire
    echo $user->pivot->role->name;
}
```

### Utiliser des noms de relations non standards

Si les méthodes `belongsTo` du modèle pivot ne suivent pas la convention de nommage standard (nom du modèle en camelCase singulier), vous pouvez les spécifier explicitement via les arguments de `chaperone()`.

```php theme={null}
return $this->belongsToMany(User::class)
    ->using(RoleUser::class)
    ->chaperone(declaring: 'role', related: 'user');
```

<Tip>
  `chaperone()` est un mécanisme qui résout le « problème N+1 » y compris pour les références transitant par la table intermédiaire. Il est particulièrement efficace, combiné à l'eager loading habituel via `with()`, pour les applications qui accèdent fréquemment aux informations des modèles parents depuis le pivot (par exemple, afficher ensemble la date d'approbation et le nom d'utilisateur).
</Tip>

## Étapes suivantes

<Card title="Relations Eloquent" icon="link" href="/fr/eloquent-relationships">
  Revenez sur la définition des relations de base, dont belongsToMany.
</Card>

<Card title="Observers Eloquent et événements de modèle" icon="bolt" href="/fr/advanced/eloquent-observers">
  Apprenez à utiliser les événements de modèle pour intercepter la sauvegarde et la mise à jour d'un modèle pivot.
</Card>


## Related topics

- [Introduction aux relations Eloquent](/fr/eloquent-relationships.md)
- [Guide de mise à niveau de Laravel 12 vers 13](/fr/blog/upgrade-12-to-13.md)
- [Casts personnalisés Eloquent](/fr/advanced/eloquent-casts.md)
- [Implémenter un guard d'authentification personnalisé](/fr/advanced/custom-auth-guard.md)
- [Modèles](/fr/packages/laravel-copilot-sdk/models.md)
