Tutoriel Vidéo Laravel belongsToMany : Système de tags

Télécharger la vidéo Télécharger les sources

Dans ce tutoriel nous allons voir un cas concret de relation belongsToMany en mettant en place un système de Tags pour nos articles. Pour gérer ce système on souhaite unitiliser une simple chaine de caractère "tag1, tag2, tag3...".

Afin de s'assurer que notre code fonctionne correctement nous allons utiliser le principe du BDD (behaviour driven development). Si vous voulez essayer de créer de commencer le code sans la vidéo vous pouvez essayer d'utiliser ces tests pour vous assurer que le code écrit fonctionne correctement.

<?php

namespace Tests\Feature;

use App\Post;
use App\Tag;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class TaggableTest extends TestCase
{

    public function setUp()
    {
        parent::setUp();
        Artisan::call('migrate');
    }

    public function listenQueries () {
        Event::listen('Illuminate\Database\Events\QueryExecuted', function ($query)  {
            echo "\033[0;34m" . $query->sql . "\033[0m <= ";
            echo "\033[0;32m[" . implode(', ', $query->bindings) . "]\033[0m";
            echo "\n";
        });
    }

    public function testCreateTags()
    {
        $post = factory(Post::class)->create();
        $post->saveTags('salut,chien,chat,chat');
        $this->assertEquals(3, Tag::count());
        $this->assertEquals(1, Tag::first()->post_count);
        $this->assertEquals(3, DB::table('post_tag')->count());
    }

    public function testEmptyTags()
    {
        $post = factory(Post::class)->create();
        $post->saveTags('');
        $this->assertEquals(0, Tag::count());
    }

    public function testReuseTags()
    {
        $posts = factory(Post::class, 2)->create();
        $post1 = $posts->first();
        $post2 = $posts->last();
        $post1->saveTags(' salut, chien, chat , , ');
        $post2->saveTags('salut ,chameau');
        $this->assertEquals(4, Tag::count());
        $this->assertEquals(3, DB::table('post_tag')->where('post_id', $post1->id)->count());
        $this->assertEquals(2, DB::table('post_tag')->where('post_id', $post2->id)->count());
        $this->assertEquals(2, Tag::where('name', 'salut')->first()->post_count);
    }

    public function testPostCountOnTags() {
        $posts = factory(Post::class, 2)->create();
        $post1 = $posts->first();
        $post2 = $posts->last();
        $post1->saveTags('salut,chien,chat');
        $this->assertEquals(1, Tag::where('name', 'salut')->first()->post_count);
        $post2->saveTags('salut');
        $this->assertEquals(2, Tag::where('name', 'salut')->first()->post_count);
        $post2->saveTags('chien');
        $this->assertEquals(2, Tag::where('name', 'chien')->first()->post_count);
        $this->assertEquals(1, Tag::where('name', 'salut')->first()->post_count);
    }

    public function testCleanUnusedTags () {
        $post = factory(Post::class)->create();
        $post->saveTags('salut,chien,chat');
        $this->assertEquals(3, Tag::count());
        $post->saveTags('');
        $this->assertEquals(0, Tag::count());
    }

    public function testDeletePost () {
        $post = factory(Post::class)->create();
        $post->saveTags('salut,chien,chat');
        $this->assertEquals(3, Tag::count());
        $post->delete();
        $this->assertEquals(0, Tag::count());
    }

    public function testDuplicateTags () {
        $post = factory(Post::class)->create();
        $post->saveTags('salut, Salut');
        $this->assertEquals(1, Tag::count());
    }
}