Eloquent et les Relations

N'avez-vous jamais voulu maîtriser les Relation que Laravel dispose ? Nous allons voir ensemble 9 relations que je juge indispensable pour devenir un pro !Dans cette leçon tout sera fait pour que même un bébé apprenant à marcher puisse comprendre. :D

Eloquent est un outil très puissant qui permet de gérer de manière très simple et intuitif vos base de données. Il s’occupe entièrement de tout, que cela soit pour enregistrer des données, les mettre à jour, les supprimer, les récupérer etc… Mais pas que ! Il peut également manipuler les données comment beau vous semble et relier les tables les une aux autres très facilement avec les relations.

Dans cette leçon nous allons voir ce que Eloquent à sous le capot en matière de Relation. Je me baserai sur la documentation de Laravel, ainsi que sur mes connaissances personnelles afin de vous expliquer le mieux que possible !

Si jamais vous avez besoin d’un support visuel, j’ai crée une série Eloquent & les Relations. Cette série reprend toutes les relations que nous allons aborder dans cette leçon, mais comme j’aime que les séries soient le plus simple possible, je n’ai pas pu tout aborder par peur que vous vous en lasser.

Nous verrons dans cette leçon 9 relations :

Cela fait beaucoup n’est-ce pas ? Point d’inquiètude ! Vous verrez que cela vous semblera très facile de les connaitre si vous pratiquer très souvent. Et je n’ai pas envie de vous faire peur ou de vous faire abandonner dès le début en vous disant qu’il y a également d’autres relations que nous ne verrons pas dans cette leçon.

Toujours là ? Alors si vous avez les reins solides, je vous propose que nous commençions en douceur avec la relations hasOne().

hasOne() – Un par un

La relation hasOne() est de très loin la relation la plus facile ! Le but est de dire « qu’un enregistrrement possède un enregistrement ». Pour faire plus simple :
Un utilisateur possède un profil.
C’est plus parlant comme ça. Mais vous n’êtes en aucun cas obligé de prendre mon exemple, le mieux serait que vous pratiquer en même temps que moi mais en utilisant vos propres exemple (par exemple un policier possède une voiture etc…).
Je suppose que vous avez déjà deux tables, toutes deux attachées à un Modèle.
Moi j’ai la table users pour le Modèle User.php et la tables profiles pour Profile.php.
Pour créer un Modèle avec sa migrations (table) :

php artisan make:model Profile -m

Comme je l’ai dit tantôt un utilisateur possède un profil, cela veut dire que je ne vais toucher que le Modèle User.php et rajouter ce code :

public function profile()
{
    return $this->hasOne('App\Profile');
}

Pour mieux comprendre, sachez que Laravel utilise des conventions, je ne serais que mieux vous conseiller que de les suivre.
Déjà vous avez vu que j’ai utiliser une méthode publique (sinon on ne pourra pas utiliser les relations en dehors !). Puis le nom de la méthode est « profile » au singulier, car on dit qu’un utilisateur possède un profil, que de plus logique de le mettre au singulier. 😉
Ensuite je retourne un « $this->hasOne() », la méthode hasOne() veut tout simplement dire « possède un » et à l’intérieur on met le nom avec qui on souhaiterai faire la relation. Ici c’est avec le Modèle Profile.php.
Et pour terminer il faut aller dans la migrations xxxx_create_profiles_table.php qui se trouve dans database > migrations.
Et il faut ajouter une clé étrangère qui fera la relation avec la tables users.

public function up()
{
    Schema::create('profiles', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('user_id')->index();
        $table->string('facebook');
        $table->string('phone');
        $table->integer('age');
        $table->timestamps();
    });
}

J’ai rajouté des colonnes supplémentaires comme facebook pour l’URL du profil facebook de l’utilisateur, son numéro téléphonique et son âge.
Mais le plus important est la colonne user_id, ici la convention est de reprendre le nom de la table avec qui on souhaiterai faire la relation, dans notre cas c’est la tables « users ». Mais celui-ci doit être au singulier (donc user) et de rajouter un undescord suivi du mot clé id (_id).
Cette colonne va contenir l’ID des utilisateurs, comme ça Laravel va récupérer l’utilisateur juste avec son ID pour faire la relation.

Table de relation hasOne - Un à un

Puis il vous suffit de relancer la migration

php artisan migrate:fresh

Et de créer des nouveaux enregistrements. Je vous conseil d’utiliser les Factories & Seeds pour gagner du temps.

Et pour récupérer un profil avec son profil :

App\User::first()->profile->facebook

Et pour récupérer tous les utilisateurs avec leurs profils :

@foreach($users as $user)
    {{ $user->profile->facebook }}
    ...
@endforeach

Je vous l’ai dit, c’est de loin la relation la plus facile !

Créer un profil automatiquement

Avec ce genre de relation un à un, parfois il est crusial dès le début de la création d’un enregistrement, ici à l’occurence un utilisateur. Il faut immédiatement créer son profil.
On peut le faire via le Controller ou via les évenements.

Via le Controller

use App\User;
use Illuminate\Http\Request;

public function store(Request $request)
{
    $user = User::create($request→all())
    
    $user→profile()→create() ;
}

Cela va automatiquement créer un profil pour l’utilisateur qui sera enregistrer. Cela va simplement remplir le user_id mais il faut bien évidement que les autres colonnes soient en nullable (qui peuvent accepter les valeurs nulles).

Via les événements

Je ne vais pas créer de class d’événement, je vais plutôt utiliser les événements qu’on peut appeler dans les Modèles.

class User extends Authenticatable implements MustVerifyEmail
{
    use Notifiable;

    protected static function boot()
    {
        parent::boot();

        static::created(function ($model) {
            $model->profile()->create();
        });
    }
]

On utilise les événements avec la méthode created() dans le Modèle User.php, ce qui veut dire après la création d’un utilisateur, tu vas m’éxecuter ce qui suit.

Voilà avec ceci vous voilà devenu un pro en relation hasOne(). Bravo ! :D

belongsTo() – Appartient à …

Comme pour la relation hasOne(), le relation belongsTo() est également l’une des plus simple.

Prenons l’exemple du chapitre précédent, nous avons dit qu’un utilisateur possède un profil, n’est-ce pas ? Alors on peut aussi faire l’inverse en disant qu’un profil appartient à un utilisateur.

Pour cela il suffit de rajouter la relation dans le Modèle en question, ici c’est Profil.php.

public function user()
{
    return $this->belongsTo(‘App\User’);
}

Et pour récupérer l’utilisateur en passant par le profil :

$profile = App\Profile::first();

$profile->user->name;

Mais contrairement à la relation hasOne() vous ne pouvez pas créer d’enregistrement en utilisant la relation belongsTo().

// Cela est complétement insencé !
$profile = App\Profile::first();

$profile->user()->create();

En même temps cela est logique, vous ne pouvez pas créer de profil puis créer par la suite l’utilisateur qui sera attaché a ce profil, non ? 😉

hasMany() - Possède plusieurs ...

La relation hasMany() est identique à la relation hasOne(), la différence est que le hasMany() prend en charge plusieurs enregistrements.

Prenons pour exemple une table qui contient des articles, nous l’appelerons « posts ». Bien évidenment qu’il faut également créer le Modèle Post.php :

php artisan make:model Post -m

Imaginons maintenant qu’un article appartient à un utilisateur, par logique on pourrait se dire :
Un article appartient à un utilisateur et un utilisateur peut avoir plusieurs articles.

Logique, n’est-ce pas ? ;-)
Si on suit bien la logique, c’est donc dans la tables posts que nous devrons mettre la clé étrangère user_id.

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('user_id')->index();
        $table->string('name');
        $table->string('slug')->nullable();
        $table->text('body');
        $table->timestamps();
    });
}

Table de relation hasMany - Un à plusieurs

Puis dans le Modèle User.php, c’est là que nous devrons mettre en place la relation :

public function posts()
{
    return $this->hasMany(‘App\Post’);
}

Et c’est fini ! Il vous suffit de relancer la migration (de préférence avec des Seeds).

Pour récupérer des articles appartenant à un utilisateur :

$user = App\User::first();

$posts = $user→posts()->get();

// Cela veut dire la même chose :

$posts = $user→posts;
Comme pour la relation hasOne(), vous pouvez également faire l’inverse en disant qu’un article appartient à un utilisateur. Pour cela utilisez la relation belongsTo().

Si on souhaite enregistrer un article tout en remplissant automatiquement le champ user_id

use App\User;
use Illuminate\Http\Request;

public function store(Request $request)
{
    // En récupérant un utilisateur dans la BDD :

    $user = App\User::first();

    $post = $user→posts()→create($request→all());

    // En récupérant l’ID de l’utilisateur connecté :

    $post = auth()->user()→posts()->create($request->all());
}

Avec cela, Laravel complétera automatique le champ user_id en indiquant l’ID de l’utilisateur.

hasManyThrough() – Possède plusieurs à travers …

Toujours là ? Bien, nous commençons a rentrer dans le vif du sujet, alors accrochez-vous bien les amis !

La relation hasManyThrough() est un peu particulière, elle n’est pas du tout compliquée mais on peut faire des erreurs très facilement avec cette relation.

L’exemple que j’aime énormement est celle du nombre d’habitant dans un pays.
Disant que nous avons 3 tables : countries, cities et peoples.

php artisan make:model Country -m
php artisan make:model City -m
php artisan make:model People -m

Et en toute logique un pays contient des villes, et chaque ville contienne des habitants. Donc un habitant appartient à une ville et une ville appartienne à un Pays.

Si vous souhaitez récupérer tous les habitants d’un pays, comment vous le ferez ?

Si vous répondez en mettant une clé étrangère dans la tables peoples pardi !. Alors je vous arrête tout de suite ! Ce n’est pas du tout la bonne approches !

L’astuce est d’utiliser justement la table cities comme passerèle entre les tables countries et peaples. Car justement la tables cities est liée entre ces deux tables !

Dans la migration countries :

public function up()
{
    Schema::create('countries', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}

Dans la migration cities :

public function up()
{
    Schema::create('countries', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('country_id')->index();
        $table->string('name');
        $table->timestamps();
    });
}

Et pour finir, la table peaple :

public function up()
{
    Schema::create('peoples', function (Blueprint $table) {
        $table->increments('id');
        $table->unsignedInteger('city_id')->index();
        $table->string('name');
        $table->string('adresse')
        $table-> string ('postcode');
        $table->timestamps();
    });
}

Si vous avez une bonne mémoire, directement vous devrez rajouter les relations hasMany() dans le Modèle Country et City :

// Country.php
public function cities()
{
    return $this->hasMany(‘App\City’);
}
// City.php
public function peoples()
{
    return $this->hasMany(‘App\People’);
}

Et si vous souhetez récupérer les villes ou les habitants vous ferez quelque chose de ce genre :

// Récupération de ville:
$country = App\Country::first();

$country->cities

// Vous ^pouvez faire directement :
// App\Country::first()->cities;



// Récupération des gens :
$city = App\City::first();

$city->users

// Vous ^pouvez faire directement :
// App\City::first()->users;

Mais nous on souhaite récupérer directement les habitants et non les villes ! Et c’est là que la relation hasManyThrough() rentre en action !

Il suffit tout simplement d’aller dans le Modèle Contry (normal puisqu’on veut récupérer les habitants d’un pays), puis de rajouter cette relation :

public function peoples()
{
    return $this-> hasManyThrough (‘App\People’ , ‘App\City’);
}

La méthode hasManyThrough() prend dans ce cas là deux arguments :
En premier le Modèle avec qui on souterait faire la relation, ici c’est le People.php.

Et en deuxième, le Modèle qui nous servira de passerelle, c’est donc City.php.

// Récupération de ville:
$country = App\Country::first();

$country->users;

// Vous ^pouvez faire directement :
// App\Country::first()->users;

Essayez ! Vous verrez que cela fonctionne parfaitement ! :D

belongsToMany() – Plusieurs à plusieurs

Les choses se corse de plus en plus ! La relation belongsToMany() fait partie de ces relations qui nécessitent une table pour faire la liaison entre deux tables.
Normalement tout de suite, ce qui vous viendrez à l’esprit est à la relation hasManyThrough(). En fait c’est différent car cette fois-ci il faut créer une table spécialement conçue pour la relation belongsToMany(), on appelle cette table : une table de pivot (ou pivot tout simplement).

Je suis sûr que vous avez déjà croisé ce type de relation sans même vous en rendre compte ! Non ? Vous êtes certain ? O.ô

Losque vous naviguer sur des sites, plus précisément dans des blogs, vous avez déjà vu des tags (ou étiquettes) sur ces derniers, non ? Alors comment fait-on pour attacher des tages à des articles ?

Sachant qu’un tags peut posséder plusieurs articles et un articles peut posséder également plusieurs tags.

C’est tout simplement impossible de faire un lien direct entre deux tables dans ce cas présent, c’est pouquoi une table de pivot est nécessaire !

Le principe est très simple, on crée une table qui va contenir deux clés étrangères, ici dans notre cas, une clé étrangère pour les articles et une autres pour les tags.

Créons pour cela nos Modèles ainsi que leurs migrations :
php artisan make:model Post -m
php artisan make:model Tag -m

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->text('body');
        $table->timestamps();
    });
}
public function up()
{
    Schema::create(tags, function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->timestamps();
    });
}

Mais ce n’est pas tout, il faut également créer la table de pivot pour faire la relation belongsToMany().

php artisan make:migration create_post_tag_table --create=post_tag

Une convention est très importante à respecter :

  • On met toujours les deux tables par ordre alphabétique, le p de posts vient avant le t de tags.
  • On met les noms des tables mais au singulier donc post et tag pour former : post_tag.
public function up()
{
    Schema::create(post_tag, function (Blueprint $table) {
        $table->increments('id');
        $table-> unsignedInteger ('post_id');
        $table-> unsignedInteger ('tag_id');

        $table->timestamps();
    });
}

Maintenant il vous suffit de relancer la migration :

php artisan migrate:fresh

Puis nous allons faire la relation, allez d’abord dans le Modèle Post.php et rajoutez :

public function tags()
{
    return $this-> belongsToMany(‘App\Tag’);
}
 

Puis nous allons faire de même pour le Modèle Tag.php :

public function posts()
{
    return $this-> belongsToMany(‘App\Post’);
}

Bingo ! La relation est établie entre les tables posts et tags !
Relation belongsToMany()

Vous pouvez ouvrir tinker pour commencer à tester !
php artisan tinker

Par exemple pour lier l’article 2 au tag 3 come peut faire ceci :

$post = App\Post::find(2);

$post->tags()->attach(3)

Pour récupérer tous les tags de l’article 2 :

App\Post::find(2)->tags;
// Ce code est identique à :
App\Post::find(2)->tags()->get();

Ou je peut attacher le tag 4 à l’article 5 :

App\Tag::find(4) ->posts()->attach(5)

On peut également faire défaire des relations en utilisant la méthode detach().

App\Tag::find(4) ->posts()->detach(5)

Les méthodes attach() et detach() peuvent prendre un tableau contenant les IDs qu’on souhaiterai attacher ou détacher.

App\Post::first() ->tags()->attach([1, 3, 5, 10])

On peut également faire :

$tags = App\Tag::find([3, 6, 8]);

App\Post::first() ->tags()->attach($tags)

Voici un petit schéma qui explique le fonctionnement de la relation belongsToMany()
Fonctionnement de la relation belongsToMany()

morphTo() & morphMany() – Relations Polymorphiques (Un a plusieurs)

Une relation polymorphiques est utilisée dans le but d’éviter de créer plusieurs tables répétitives. Pour mieux comprendre son fonctionnement, imaginez une table qui contient des articles (posts), puis avec une relation hasMany() on mettra en relation avec une table qui contient des commentaires (comments). Puis imaginez que je vais créer une autres tables mais qui va contenir cette fois-ci des tutoriels (tutorials), mais je souheraiterai également rajouter des commentaires à un tutoriel. Comment le ferez-vous ? Vous allez créer une autre table spéciale pour les commentaires des tutoriels ?

Je ne vous le cache pas que moi aussi j’aurai eu cette idée… Mais pourquoi ne pas utiliser la même tables comments pour contenir à la fois les commentaires des articles et à la fois les commentaires des tutoriels ?

Pas possible ! Tu m’as pris pour le dernier des lapins crétins ou quoi ? Comment cela est possible ?

Allons ! Vous êtes le premier placer pour savoir qu’en programmation seule notre imagition à des limites ?

En fait le principe est simple, il suffit de mettre en place une relation (que Laravel s’en chargera de le faire) à l’intérieur d’une colonne de la table comments, puis de mettre une clé étrangère qui contiendra les IDs de nos relations.

Bon bref fini le bavardage, la pratique est mieux que la théorie ! Commençons par créer nos tables posts , tutoriels et comments avec leur Modèles.

php artisan make:model Post -m
php artisan make:model Tutorial -m
php artisan make:model Comment -m

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->text('body');
        $table->timestamps();
    });
}
public function up()
{
    Schema::create('tutoriels', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->text('body');
        $table->timestamps();
    });
}
public function up()
{
    Schema::create('comments', function (Blueprint $table) {
        $table->increments('id');
$table->unsignedInteger('commentable_id')->index();
$table->string ('commentable_tyoe');
        $table->text('body');
        $table->timestamps();
    });
}

Pour les tables posts et tutorials, rien de bien compliqué. Mais regardez la table comments, vous remarquez deux colonnes un peu spéciales commentable_id et commentable_type.
Ces deux colonnes sont très importanes dans une relations polymorphiques. Le mot clé commentable est super important car celui-ce vous servira à établir la relation, vous comprendrez pourquoi.
Le _id de commentable_id va contenir l’ID de votre relation, c’est la clé étrangère entre autres. En gros si on commente un article, on mettra l’ID de l’article, si c’est un tutoriel ce sera l’ID du tutoriel.
Et le _type de commentable_type va contenir le Modèle de la relation. Si on comment un article alors on mettra App\Post, un tutoriel App\Tutorial. Bref vous avez compris le principe.

Pour mettre en place la relation `, on va se diriger vers le Modèle Comment.php`.

public function commentable()
{
    return $this->morphTo();
}

Voilà c’est tout ! Avec cette relation on dit que la table comments appartient à plusieurs autres tables.

Mais vous avez constaté que j’ai egalement mis le mot clé commentable comme nom de la relation ? D’où l’importance de bien choisir son mot clé dans la migration.

Hummm… Et je risque d’aller loin avec ça ?

Non pas du tout ! 😊 Il faut également mettre la relation au sens inverse pour dire qu’une table possède plusieurs commentaires.

// Post.php
public function comments()
{
    return $this->morphMany(‘App\Comment’, ‘commentable’);
}
// Tutorial.php
public function comments()
{
    return $this->morphMany(‘App\Comment’, ‘commentable’);
}

La relation morphMany() prend deux paramètres ;
Le Modèle avec qui on souhaiterai mettre en relation (App\Comment) et le nom de la relation (commentable).

Voici un shéma qui résume cette type de relation polymorphoique :
 morphTo() & morphMany()

Et voilà ! Cela fonctionne comme un relation classique (hasMany() et belongsTo()).

// Récupération d’un article
$post = App\Post::first();

// Création d’un nouveau commentaire
$post->comments()->create([‘body’ => ‘Hello les gens!’]);

// Récupération du premier commentaire d’un article
$comment = $post->comments()->first();

// Récupération de tous les commentaires d’un article au plus récent
$comments = $post->comments()->orderByDesc(‘created_at’)->get();

foreach($comments as $comment)
{
	$comment->body;
}

Ici j’ai utilisé les articles comme exemple, mais vous pouvez faire de même pour les tutiriels.
Sachez également que grâce à cette relation, vous pouvez mettre des commentaires partout dans vos Modèles !
Vous pouvez également créer un système de Like pour aimer tous vos Modèles, comme l’exemple de Facebook, on peut aimer des photos, des publications, des commentaires etc… Et on peut également tout commenter sur facebook.

morphToMany() & morphedByMany() – Relations Polymorphiques (Plusieurs a plusieurs)

Nous avons vu dans le chapitre précédent morphTo() & morphMany(), qu’une table peut appartenir à plusieurs autres tables. Voyons à présent une relation identique mais cette fois-ci plusieurs tables peuvent appartenir à plusieurs autres tables.

Si vous avez bien suivi cette leçon, vous devriez vous posez la question suivante :

Mais nous avons déjà vu dans le chapitre belongsToMany(), que plusieurs tables peuvent appartenir à plusieurs autres tables avec une table de pivot.

Si vous vous êtes interrogé là-dessus, bravo ! Vous méritez mon respect ! 😉

En fait reprenons justement la relation belongsToMany(), nous avons pris l’exemple des tags et des articles. Nous avons utilisés une table de pivot (post_tag) afin de relier les tags aux articles.
Mais en plus des articles, nous souhaitons également taguer des tutotiels, des images etc… Comment vous le feriez ?

Ha mais si j’ai envie de taguer des images, je n’aurai qu’à créer une autres table de pivot image_tag pardi !

Hum… Mouais… Cela fonctionnera sûrement, si je comprends bien cela ne vous fait rien d’avoir une base de donnée rempli de tables de pivots ? Ce n’est pas très malin du tout ça…

Je vous propose une autre solution, et si on combinait à la fois les relations polymorphiques du chapitre présent avec la relation belongsToMany ? :D

Allez ! Commençons comme d’habitude par créer des Modèles ainsi que leurs migrations :

php artisan make:model Post -m
php artisan make:model Tutorial -m
php artisan make:model Tag -m

public function up()
{
    Schema::create('posts', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->text('body');
        $table->timestamps();
    });
}
public function up()
{
    Schema::create('tutoriels', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name');
        $table->text('body');
        $table->timestamps();
    });
}
public function up()
{
    Schema::create(tags, function (Blueprint $table) {
        $table->increments('id');
        $table-> string (name');
        $table->timestamps();
    });
}

Jusqu’à present, rien de bien méchant ! Maintenons il nous faut créer une table de pivot qui nous servira de table de relations polymorphiques.

php artisan make:migration create_taggables_table --create=taggables

Ici ce n’est plus la combinaisaon de deux tables, mais carrément le nom qui nous servira de relation pour le nom de la migration. Dans notre cas c’est taggables. Faites très attention car c’est considéré comme une table normal pour Laravel, comme il faut le mettre au pluriel !

public function up()
{
    Schema::create(taggables, function (Blueprint $table) {
        $table->increments('id');
        $table-> unsignedInteger ('tag_id');
$table->unsignedInteger('taggable_id')->index();
$table->string ('taggable_tyoe');
        $table->timestamps();
    });
}

Comme dans notre exemple on souhaiterait mettre des tags un peu partout, c’est donc normal de mettre une clé étrangère tag_id car c’est le point en commun avec toutes les autres tables.

Encore une fois le mot clé taggable dans les colonnes taggale_id et taggable_type sont très importants pour la suite. Donc choissiez bien le mot clé.

Après avoir lancer la migration, nous allons allez dans les Modèles qu’on souhaiterai rajouter des tags, dans notre cas c’est Post.php et Tutorial.php.

// Post.php
public function tags()
{
    return $this-> morphToMany(‘App\Tag’, ‘taggable’);
}
// Tutorial.php
public function tags()
{
    return $this-> morphToMany(‘App\Tag’, taggable’);
}

Nous utilisons cette fois-ci le relation morphToMany() qui dit en gros possède plusieurs à travers une relations polymorphiques. Puis il prend deux argument, le premier est le Modèle qui sera le point en commun avec les autres Modèles, ici c’est bien le Modèle Tag.php.
Comme pour les relations polymorphiques, nous rajoutons le mot clé taggable en deuxième paramètre.

Il ne manque plus qu’à faire la relation au sens inverse, donc dans le Modèle Tag.php
:

// Relation avec les articles
public function posts()
{
    return $this-> morphedByMany(‘App\Post’, taggable’);
}

// Relation avec les tutoriels
public function tutorials()
{
    return $this-> morphedByMany(‘App\Tutorialt’, taggable’);
}

Et oui les amis, cette fois-ci nous sommes obligés de mettres deux relations, une pour les articles avec la méthode posts() et une autres pour les tutoriels avec la méthode tutorials().

Cela fonctionne comme pour la relation belongsToMany(), avec les méthodes attach(), detach() et sync().

// Attacher des tags à un articles avec la méthodes attach()
App\Post::find(5)->tags()->attach([2, 3, 5]);

// Attacher des tags à un articles avec la méthodes sync()
App\Post::find(7)->tags()->sync([1, 3, 4]);

// Détacher un tag à un article avec la méthodes detach()
App\Post::find(5)->tags()->detach(2);

// Récuoérer les tags d’un artilce
App\Post::first()->tags

J’ai utilisé dans cet exemple les articles, mais vous pouvez bien évidement le faire avec les tutoriels.

Voici un shéma qui résume le fonctionnement de cette relation assez complexe :
Relations morphToMany() & morphedByMany()

Résumé

Comme je vous l’ai dit dans l’introduction de cette leçon, nous n’allons voir que 9 types de relations fréquement utilisées dans Laravel. Mais cela ne veut pas dire qu’il y en a que 9 ! Bien au contraire, Laravel regorge plein d’autres relations mais presque inutiles ou peu utile pour le commun des mortels 😉

Ne recopier pas bêtement mes exemples, essayez de trouvez vos propose exemple, vous apprendrez mieux et vite !