Relations Un-à-Plusieurs dans Laravel : Maîtrisez hasMany Facilement
Tutoriel sur la relation hasMany
dans Laravel
Comprendre hasMany
dans Laravel
La relation hasMany
dans l'ORM Eloquent de Laravel permet de définir une association un-à-plusieurs entre les modèles. Cela signifie qu'une instance de modèle unique (parent) peut avoir plusieurs modèles associés (enfants). Voici un scénario courant :
- Modèle parent :
Utilisateur
- Modèle enfant :
Article
Un utilisateur peut avoir plusieurs articles associés.
Configuration des modèles
-
Tables de base de données
- Assurez-vous d'avoir des tables de base de données distinctes pour les
utilisateurs
et lesarticles
. La tablearticles
doit généralement avoir une colonne de clé étrangère faisant référence à l'identifiant de l'utilisateur (user_id
) dans la tableutilisateurs
.
- Assurez-vous d'avoir des tables de base de données distinctes pour les
-
Définitions des modèles
- Créez des classes PHP distinctes pour les modèles
Utilisateur
etArticle
, généralement situées dans le répertoireapp/Models
:
PHP
// Utilisateur.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Utilisateur extends Model { use HasFactory; protected $fillable = ['nom', 'email']; public function articles() { return $this->hasMany(Article::class); } } // Article.php <?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Article extends Model { use HasFactory; protected $fillable = ['titre', 'contenu', 'user_id']; public function utilisateur() { return $this->belongsTo(Utilisateur::class); } }
-
La méthode
hasMany
dans le modèleUtilisateur
définit la relation. Elle prend deux arguments :- La classe du modèle associé (
Article::class
) - (Facultatif) Le nom de la clé étrangère sur le modèle enfant (par défaut, il s'agit du snake case du nom du modèle parent plus
_id
, qui estuser_id
dans ce cas).
- La classe du modèle associé (
-
La méthode
belongsTo
dans le modèleArticle
définit la relation inverse, indiquant qu'un article appartient à un seul utilisateur.
- Créez des classes PHP distinctes pour les modèles
Utilisation de la relation hasMany
Maintenant que les relations sont définies, vous pouvez les utiliser dans votre application Laravel :
-
Récupération des articles d'un utilisateur
- Trouvez un utilisateur en utilisant
Utilisateur::find(1)
(remplacez1
par l'identifiant réel de l'utilisateur). - Accédez aux articles de l'utilisateur en utilisant la propriété
articles
:
PHP
$utilisateur = Utilisateur::find(1); $articles = $utilisateur->articles; // Parcourir les articles foreach ($articles as $article) { echo $article->titre . '<br>'; }
- Trouvez un utilisateur en utilisant
-
Création d'articles avec un utilisateur
- Créez une nouvelle instance d'utilisateur.
- Définissez les attributs de l'utilisateur (
nom
,email
). - Créez des articles et associez-les à l'utilisateur en utilisant la méthode de relation
articles
:
PHP
$utilisateur = new Utilisateur; $utilisateur->nom = 'Jean Dupont'; $utilisateur->email = 'jean.dupont@exemple.com'; $article1 = new Article(['titre' => 'Article 1', 'contenu' => 'Ceci est le premier article']); $article2 = new Article(['titre' => 'Article 2', 'contenu' => 'Ceci est le second article']); $utilisateur->articles()->saveMany([$article1, $article2]); // Enregistre les deux articles et les associe à l'utilisateur // Ou, créez des articles directement dans la méthode save $utilisateur->save([ 'articles' => [ ['titre' => 'Article 1', 'contenu' => 'Ceci est le premier article'], ['titre' => 'Article 2', 'contenu' => 'Ceci est le second article'], ], ]);
-
Considérations supplémentaires
- Chargement avide (Eager Loading) : Pour récupérer les articles de l'utilisateur en même temps que l'utilisateur
- Pour récupérer les publications de l'utilisateur avec l'utilisateur en une seule requête, utilisez
with
lors de la récupération de l'utilisateur : -
$utilisateur= User::with('articles')->find(1);
load
-
La méthode
load
est particulièrement utile lorsque vous n'avez pas nécessairement besoin de charger les modèles associés dès la récupération du modèle parent. Vous pouvez décider de ne les charger que lorsque cela est nécessaire, ce qui peut améliorer les performances :PHP
$utilisateur = Utilisateur::find(1); // Vérifiez si les articles n'ont pas encore été chargés if (!$utilisateur->relationLoaded('articles')) { $utilisateur->load('articles'); } // Maintenant, vous pouvez accéder aux articles de l'utilisateur : foreach ($utilisateur->articles as $article) { echo $article->titre . '<br>'; }
Chargement de relations spécifiques avec
load
Vous pouvez également spécifier les relations à charger en utilisant un tableau de noms de relations comme arguments de
load
:PHP
$utilisateur = Utilisateur::find(1); $utilisateur->load(['articles', 'commentaires']); // Charger à la fois les articles et les commentaires
Chargement de relations avec des conditions avec
load
Pour un contrôle plus granulaire, vous pouvez passer une closure à la méthode
load
afin d'appliquer des conditions à la requête du modèle associé :PHP
$utilisateur = Utilisateur::find(1); $utilisateur->load(['articles' => function ($query) { $query->where('publie', true); // Charger uniquement les articles publiés }]); foreach ($utilisateur->articles as $article) { echo $article->titre . '<br>'; }
loadMissing
vs.load
- Utilisez
loadMissing
si vous avez déjà récupéré le modèle parent et que vous voulez charger uniquement les relations manquantes : -
PHP
$utilisateur = Utilisateur::find(1); $utilisateur->loadMissing('articles'); // Charger uniquement les articles s'ils ne sont pas déjà chargés
N'oubliez pas que
load
etloadMissing
exécutent des requêtes distinctes pour récupérer les modèles associés. Si vous savez que vous aurez certainement besoin des modèles associés, envisagez d'utiliser le chargement avide (eager loading) avecwith
pour de meilleures performances dans une seule requête de base de données. Choisissez l'approche qui convient le mieux à votre cas d'utilisation et à vos besoins en matière de performances.