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
utilisateurset lesarticles. La tablearticlesdoit 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
UtilisateuretArticle, 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
hasManydans le modèleUtilisateurdé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_iddans ce cas).
- La classe du modèle associé (
-
La méthode
belongsTodans le modèleArticledé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)(remplacez1par 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
withlors de la récupération de l'utilisateur : -
Chargement conditionnel avec$utilisateur= User::with('articles')->find(1);load -
La méthode
loadest 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
loadVous 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 commentairesChargement de relations avec des conditions avec
loadPour un contrôle plus granulaire, vous pouvez passer une closure à la méthode
loadafin 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>'; }loadMissingvs.load - Utilisez
loadMissingsi 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ésN'oubliez pas que
loadetloadMissingexé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) avecwithpour 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.