Laravel 8

Créer un blog – les données

On a vu dans le précédent article la présentation générale du projet de blog et on a aussi créé un Laravel 8 de base avec l’authentification avec Laravel Breeze. On va maintenant se lancer et on va commencer par s’intéresser aux données. Que va contenir notre base ? Quelles tables nous sont nécessaires avec quelles colonnes ? Que va-t-on avoir comme relations ? Quelle sont les données de populations qu’on va générer pour que notre blog fonctionne dès le départ ? Ce sont les bonnes questions à se poser quand on démarre un projet, même si ça évolue forcément en cours de route

Vous pouvez télécharger le code final de cet article ici.

Les données de base de Laravel

Pour le moment avec notre Laravel de base on a ces migrations :

Donc :

  • une migration pour la table users
  • une migration pour la table password_resets pour le renouvellement des mots de passe
  • une migration pour la table failed_jobs pour les tâches qui ont échoué

Comme on va utiliser le système de notifications de Laravel pour notre blog (on va même un peu le détourner) on va ajouter la migration correspondante :

php artisan notifications:table

Les utilisateurs

Par défaut la table users comporte ces colonnes :

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password');
    $table->rememberToken();
    $table->timestamps();
});

On va avoir besoin d’autres informations :

  • role : pour savoir quelles sont les permissions de l’utilisateur : administrateur, rédacteur ou simple utilisateur. Ce n’est pas la peine d’utiliser un package pour ce genre de chose.
  • valid : pour valider un utilisateur au niveau des commentaires, le premier commentaire d’un utilisateur n’apparaît pas tout de suite, il faut que ce soit validé par l’administrateur ou l’auteur de l’article, les commentaires suivants par contre apparaitront tout de suite, c’est une façon d’éviter les trolls.

On ajoute donc ces deux colonnes :

Schema::create('users', function (Blueprint $table) {
    ...
    $table->enum('role', array('user', 'redac', 'admin'))->default('user');
    $table->boolean('valid')->default(false);
    ...
});

On a déjà un modèle User. Toutefois on va ajouter les deux colonnes qu’on a créées dans la propriété $fillable :

protected $fillable = [
    'name',
    'email',
    'password',
    'role', 
    'valid',
];

C’est facile à oublier et ensuite on cherche le bug un bon moment 🙂

On dispose déjà d’un factory pour cette table (database/factories/UserFactory.php). On va juste le compléter pour mettre la colonne valid à true :

return [
    'name' => $this->faker->name,
    'email' => $this->faker->unique()->safeEmail,
    'email_verified_at' => now(),
    'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi',
    'remember_token' => Str::random(10),
    'valid' => true,
];

Les catégories

Les articles vont être organisées en catégories, on va donc créer une table pour mémoriser ces informations. On va créer simultanément le modèle et la migration :

php artisan make:model Category -m

Pour les catégories on va avoir besoin de deux informations :

  • title : le titre
  • slug : c’est le texte qui va apparaître dans l’url et qui ne doit comporter que des caractères autorisés

D’autre part on ne va pas utiliser les timestamps, quel intérêt de savoir quand une catégorie a été créée ou modifiée ? On a donc :

Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->string('title')->unique();
    $table->string('slug')->unique();
});

Pour le modèle on va supprimer le trait HasFactory qui ne nous servira pas et on crée la propriété $fillable :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    protected $fillable = [
        'title', 
        'slug',
    ];

    public $timestamps = false;
}

Les étiquettes (tags)

Les articles vont être aussi identifiables avec des étiquettes, ce qui permet une sélection transversale alors que les catégories créent une organisation verticale. On crée le modèle et la migration :

php artisan make:model Tag -m

Pour les étiquettes on va avoir besoin de deux informations comme pour les cétégories :

  • tag : le titre
  • slug : c’est le texte qui va apparaître dans l’url et qui ne doit comporter que des caractères autorisés

D’autre part on ne va pas non plus utiliser les timestamps, quel intérêt de savoir quand une étiquette a été créée ou modifiée ? On a donc :

Schema::create('tags', function(Blueprint $table) {
    $table->id();
    $table->string('tag', 50)->unique();
    $table->string('slug')->unique();
});

Pour le modèle on va aussi supprimer le trait HasFactory qui ne nous servira pas et on crée la propriété $fillable :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Tag extends Model {

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['tag'];

    public $timestamps = false;
}

Les articles (posts)

Là c’est le gros morceau évidemment ! On crée le modèle, la migration et le factory :

php artisan make:model Post -mfc

 

On va avoir besoin de pas mal d’informations :

  • title : le titre
  • slug
  • seo_title : le titre pour le SEO
  • meta_keywords : les mots clés pour le SEO
  • meta_description : la description pour le SEO
  • excerpt : le texte d’introduction (celui qui apparaît en résumé sur la page d’accueil)
  • body : le corps de l’article
  • active : pour savoir si l’article est publié
  • image : pour le nom de l’image réduite pour la page d’accueil

 

Schema::create('posts', function(Blueprint $table) {
    $table->id();
    $table->timestamps();
    $table->string('title');
    $table->string('slug')->unique();
    $table->string('seo_title')->nullable();
    $table->text('excerpt');
    $table->text('body');
    $table->text('meta_description');
    $table->text('meta_keywords');
    $table->boolean('active')->default(false);
    $table->string('image')->nullable();
});

Pour le factory on va prévoir le remplissage automatique de quelques colonnes :

public function definition()
{
    return [
        'meta_description' => $this->faker->sentence($nbWords = 6, $variableNbWords = true),
        'meta_keywords' => implode(',', $this->faker->words($nb = 3, $asText = false)),
        'excerpt' => $this->faker->paragraph($nbSentences = 4, $variableNbSentences = true),
        'body' => $this->faker->paragraphs($nb = 8, $asText = true),
        'active' => true,
    ];
}

On gèrera titre, slug et image directement dans la population.

Pour le modèle on va créer la propriété $fillable et aussi prévoir le trait Notifiable :

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use App\Events\ModelCreated;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;

class Post extends Model
{
    use HasFactory, Notifiable;

    protected $fillable = [
        'title', 
        'slug', 
        'seo_title', 
        'excerpt', 
        'body', 
        'meta_description', 
        'meta_keywords', 
        'active', 
        'image', 
        'user_id',
    ];
}

Les relations

Arrivé à ce stade il est temps de s’intéresser aux relations. On va avoir :

  • un utilisateur peut avoir plusieurs articles (et réciproquement un article appartient à un seul utilisateur)
  • une catégorie peut avoir plusieurs articles et réciproquement un article peut appartenir à plusieurs catégories
  • un article peut avoir plusieurs étiquettes et une étiquette peut appartenir à plusieurs articles

Un utilisateur a plusieurs articles

Il faut mettre une clé étrangère dans la table posts, donc dans la migration :

public function up()
{
    Schema::create('posts', function(Blueprint $table) {
        ...
        $table->foreignId('user_id')
              ->constrained()
              ->onDelete('cascade')
              ->onUpdate('cascade');
    });
}

J’ai opté pour une cascade en cas de suppression ou de modification.

Au niveau des modèles on ajoute la relation dans User :

public function posts()
{
    return $this->hasMany(Post::class);
}

Et dans Post :

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

Relation entre catégories et articles

Là c’est une relation many to many, il faut donc une table pivot :

php artisan make:migration category_post_table

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CategoryPostTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('category_post', function(Blueprint $table) {
            $table->id();
            $table->foreignId('category_id')
                  ->constrained()
                  ->onDelete('cascade')
                  ->onUpdate('cascade');
            $table->foreignId('post_id')
                  ->constrained()
                  ->onDelete('cascade')
                  ->onUpdate('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('category_post');
    }
}

On a évidemment dans cette table deux clés étrangères :

  • category_id : pour référencer la catégorie
  • post_id : pour référencer l’article

On ajoute la relation dans Category :

public function posts()
{
    return $this->belongsToMany(Post::class);
}

Et dans Post :

public function categories()
{
    return $this->belongsToMany(Category::class);
}

Relation entre étiquettes et articles

Là c’est encore une relation many to many, il faut donc une table pivot :

php artisan make:migration post_tag_table

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class PostTagTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post_tag', function(Blueprint $table) {
            $table->id();
            $table->foreignId('post_id')
                  ->constrained()
                  ->onDelete('cascade')
                  ->onUpdate('cascade');
            $table->foreignId('tag_id')
                  ->constrained()
                  ->onDelete('cascade')
                  ->onUpdate('cascade');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_tag');
    }
}

 

On a évidemment aussi dans cette table deux clés étrangères :

  • tag_id : pour référencer l’étiquette
  • post_id : pour référencer l’article

On ajoute la relation dans Tag :

public function posts()
{
   return $this->belongsToMany(Post::class);
}

Et dans Post :

public function tags()
{
    return $this->belongsToMany(Tag::class);
}

Les commentaires

Pour les commentaires on a quelque chose d’un peu spécial parce on a un système hiérarchique, on a des commentaires de commentaire, et des des commentaires de commentaire de commentaire, et ainsi de suite. Pour gérer ça on va utiliser le package NestedSet. Il faut d’abord l’installer :

composer require kalnoy/nestedset

On crée le modèle avec factory et migration :

php artisan make:model Comment -mfc

Pour la migration on a pas besoin de grand chose, juste une colonne body pour le texte du commentaire. Par contre on va ajouter les colonnes nécessaires pour la gestion des relations entre les commentaires, mais le package va bien nous aider. En plus il faut relier cette table aux utilisateurs et articles :

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCommentsTable extends Migration {

    public function up()
    {
        Schema::create('comments', function(Blueprint $table) {
            $table->id();
            $table->timestamps();
            $table->text('body');
            $table->nestedSet();
            $table->foreignId('user_id')
                  ->constrained()
                  ->onDelete('cascade')
                  ->onUpdate('cascade');
            $table->foreignId('post_id')
                  ->constrained()
                  ->onDelete('cascade')
                  ->onUpdate('cascade');
        });
    }

    public function down()
    {
        Schema::dropIfExists('comments');
    }
}

 

Pour le factory on renseigne juste body :

public function definition()
{
    return [
        'body' => $this->faker->paragraph($nbSentences = 4, $variableNbSentences = true),
    ];
}

Pour le modèle Comment on va ajouter le trait NodeTrait pour le package, et aussi Notifiable. D’autre part on crée la propriété $fillable.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Kalnoy\Nestedset\NodeTrait;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Notifications\Notifiable;

class Comment extends Model
{
    use NodeTrait, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'body', 
        'post_id', 
        'user_id', 
    ];
}

Pour les relations on a :

  • un utilisateur a plusieurs commentaires et un commentaire appartient à un utilisateur
  • un article a plusieurs commentaires et un commentaire appartient à un article

Donc dans User :

public function comments()
{
    return $this->hasMany(Comment::class);
}

Dans Post :

public function comments()
{
    return $this->hasMany(Comment::class);
}

Dans Post on va ajouter une relation spécifique pour récupérer les commentaires valides (en fait les commentaires qui ont été rédigés par un utilisateur validé) :

public function validComments()
{
    return $this->comments()->whereHas('user', function ($query) {
        $query->whereValid(true);
    });
}

Et dans Comment on précise l’appartenance à l’utilisateur et à l’article :

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

public function post()
{
    return $this->belongsTo(Post::class);
}

Une petite visualisation de la situation :

La population

Maintenant qu’on a créé les migrations essentielles vous pouvez lancer la migration pour voir si tout se passe bien :

php artisan migrate

Vous devez obtenir ces 11 tables :

Vous pouvez aussi vérifier que vous avez les bonnes colonnes dans chacune de ces tables.

On ajoutera utltérieurement d’autres tables pour les contacts, les pages… Mais pour le moment on va s’en passer et on va faire tourner le blog.

Pour nos essais on va avoir besoin de données dans les tables, on va utiliser pour ça la population (seeder) avec ce fichier :

Pour le moment la fonction run est vide (on a juste un peu de code commenté) :

public function run()
{
    // \App\Models\User::factory(10)->create();
}

Les utilisateurs

On va créer un administrateur, 2 rédacteurs et 3 utilisateurs de base :

use App\Models\{ User, Contact, Post, Comment, Page };
use Illuminate\Support\Facades\DB;

...

User::withoutEvents(function () {
    // Create 1 admin
    User::factory()->create([
        'role' => 'admin',
    ]);
    // Create 2 redactors
    User::factory()->count(2)->create([
        'role' => 'redac',
    ]);
    // Create 3 users
    User::factory()->count(3)->create();
});

$nbrUsers = 6;

J’utilise withoutEvents pour inhiber les événements, pour l’instant on n’en a pas mais on en mettra en place plus tard, du coup ça n’aura pas d’impact sur la population.

Les catégories

On crée 3 catégories :

DB::table('categories')->insert([
    [
        'title' => 'Category 1',
        'slug' => 'category-1'
    ],
    [
        'title' => 'Category 2',
        'slug' => 'category-2'
    ],
    [
        'title' => 'Category 3',
        'slug' => 'category-3'
    ],
]);

$nbrCategories = 3;

Les étiquettes

On prévoit 6 étiquettes :

DB::table('tags')->insert([
    ['tag' => 'Tag1', 'slug' => 'tag1'],
    ['tag' => 'Tag2', 'slug' => 'tag2'],
    ['tag' => 'Tag3', 'slug' => 'tag3'],
    ['tag' => 'Tag4', 'slug' => 'tag4'],
    ['tag' => 'Tag5', 'slug' => 'tag5'],
    ['tag' => 'Tag6', 'slug' => 'tag6']
]);

$nbrTags = 6;

Les articles

On crée 9 articles qu’on attribue aux 2 rédacteurs :

Post::withoutEvents(function () {
    foreach (range(1, 2) as $i) {
        Post::factory()->create([
            'title' => 'Post ' . $i,
            'slug' => 'post-' . $i,
            'seo_title' => 'Post ' . $i,
            'user_id' => 2,
            'image' => 'img0' . $i . '.jpg',
        ]);
    }
    foreach (range(3, 9) as $i) {
        Post::factory()->create([
            'title' => 'Post ' . $i,
            'slug' => 'post-' . $i,
            'seo_title' => 'Post ' . $i,
            'user_id' => 3,
            'image' => 'img0' . $i . '.jpg',
        ]);
    }
});

$nbrPosts = 9;

Pour les images je pars du principe qu’on a des images qui s’appellent img00, img01, img02…

On va attacher des étiquettes et des catégories aux articles :

// Tags attachment
$posts = Post::all();
foreach ($posts as $post) {
    if ($post->id === 9) {
        $numbers=[1,2,5,6];
        $n = 4;
    } else {
        $numbers = range (1, $nbrTags);
        shuffle ($numbers);
        $n = rand (2, 4);
    }
    for($i = 0; $i < $n; ++$i) {
        $post->tags()->attach($numbers[$i]);
    }
}

// Set categories
foreach ($posts as $post) {
    if ($post->id === 9) {
        DB::table ('category_post')->insert ([
            'category_id' => 1,
            'post_id' => 9,
        ]);
    } else {
        $numbers = range (1, $nbrCategories);
        shuffle ($numbers);
        $n = rand (1, 2);
        for ($i = 0; $i < $n; ++$i) {
            DB::table ('category_post')->insert ([
                'category_id' => $numbers[$i],
                'post_id' => $post->id,
            ]);
        }
    }
}

Les commentaires

On commence par créer des commentaires de premier niveau :

foreach (range(1, $nbrPosts - 1) as $i) {
    Comment::factory()->create([
        'post_id' => $i,
        'user_id' => rand(1, $nbrUsers),
    ]);
}

Pour les commentaires des autres niveaux le package permet d’utiliser des tableaux, ce qui est bien pratique :

$faker = \Faker\Factory::create();

Comment::create([
    'post_id' => 2,
    'user_id' => 3,
    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),

    'children' => [
        [
            'post_id' => 2,
            'user_id' => 4,
            'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),

            'children' => [
                [
                    'post_id' => 2,
                    'user_id' => 2,
                    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),
                ],
            ],
        ],
    ],
]);

Comment::create([
    'post_id' => 2,
    'user_id' => 6,
    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),

    'children' => [
        [
            'post_id' => 2,
            'user_id' => 3,
            'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),
        ],
        [
            'post_id' => 2,
            'user_id' => 6,
            'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),

            'children' => [
                [
                    'post_id' => 2,
                    'user_id' => 3,
                    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),
                
                    'children' => [
                        [
                            'post_id' => 2,
                            'user_id' => 6,
                            'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),
                        ],
                    ],
                ],
            ],
        ],
    ],
]);

Comment::create([
    'post_id' => 4,
    'user_id' => 4,
    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),

    'children' => [
        [
            'post_id' => 4,
            'user_id' => 5,
            'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),

            'children' => [
                [   'post_id' => 4,
                    'user_id' => 2,
                    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),
                ],
                [
                    'post_id' => 4,
                    'user_id' => 1,
                    'body' => $faker->paragraph($nbSentences = 4, $variableNbSentences = true),
                ],
            ],
        ],
    ],
]);

Il ne reste plus qu’à lancer la population :

php artisan db:seed

Vérifiez dans vos tables que vous obtenez bien les données attendues.

Conclusion

On dispose maintenant des tables et des données pour commencer à coder notre frontend, ce que nous feraons dans le prochain article. Il faudra aussi s’occuper des medias avec un nouveau package.

Print Friendly, PDF & Email

24 commentaires

  • fifi

    Bonjour Bestmomo et merci pour ce tutoriel,
    J’ai un problème avec la migration ( J’ai ajouté le mot de passe: DB_PASSWORD=motdepasse)
    PS C:\laragon\www\monblog> php artisan migrate

    Illuminate\Database\QueryException

    SQLSTATE[HY000] [1045] Access denied for user ‘root’@’localhost’ (using password: YES) (SQL: select * from information_schema.tables where table_schema = monblog and table_name = migrations and table_type = ‘BASE TABLE’)

    at C:\laragon\www\monblog\vendor\laravel\framework\src\Illuminate\Database\Connection.php:678
    674▕ // If an exception occurs when attempting to run a query, we’ll format the error
    675▕ // message to include the bindings with SQL, which will make this exception a
    676▕ // lot more helpful to the developer instead of just the database’s errors.
    677▕ catch (Exception $e) {
    ➜ 678▕ throw new QueryException(
    679▕ $query, $this->prepareBindings($bindings), $e
    680▕ );
    681▕ }
    682▕

    1 C:\laragon\www\monblog\vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php:70
    PDOException::(« SQLSTATE[HY000] [1045] Access denied for user ‘root’@’localhost’ (using password: YES) »)

    2 C:\laragon\www\monblog\vendor\laravel\framework\src\Illuminate\Database\Connectors\Connector.php:70
    PDO::__construct(« mysql:host=127.0.0.1;port=3306;dbname=monblog », « root », « motdepasse », [])

  • DaniBlou

    Bonjour

    Merci deja pour cette formation quentu nous offre et pour ta disponibilite

    en fait j’ai un soucis quand je veux installer laravel Breeze

    j’ai cette erreur

    PHP Warning: require(/home/daniel/BlogPro/vendor/autoload.php): Failed to open stream: No such file or directory in /home/daniel/BlogPro/artisan on line 18
    PHP Fatal error: Uncaught Error: Failed opening required ‘/home/daniel/BlogPro/vendor/autoload.php’ (include_path=’.:/usr/share/php’) in /home/daniel/BlogPro/artisan:18
    Stack trace:

    j’ai essaiye tout ce dont j’ai vu mais pas de solution. je compte sur toi pour m’aider
    merci d’avance

  • Junior Ndono Jb

    bonjour Best MOmo et merci pour ce tutoriel. Pour ma part j’ai un petit problème avec la commande **composer require kalnoy/nestedset** elle m’affiche une erreur du style
    ** [InvalidArgumentException]
    Could not find package kalnoy/nestedset.

    Did you mean one of these?
    kalnoy/nestedset
    nerio/mongo-nestedset**
    S’il vous plait j’ai besoin d’aide.

  • Michel

    Bonjour,

    Pour mon travail, j’ai besoin de construire un blog, cependant je suis un amateur aussi je vous remercie pour votre titoriel que je trouve passionnant et j’espère y arriver.

    Arrivé à ce point, je rencontre un message d’erreur:
    C:\laragon\www\monblog
    λ php artisan db:seed

    Illuminate\Database\QueryException

    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry ‘Category 1’ for key ‘categories_title_unique’ (SQL: insert into `categories` (`slug`, `title`) values (category-1, Category 1), (category-2, Category 2), (category-3, Category 3))

    at C:\laragon\www\monblog\vendor\laravel\framework\src\Illuminate\Database\Connection.php:678
    674▕ // If an exception occurs when attempting to run a query, we’ll format the error
    675▕ // message to include the bindings with SQL, which will make this exception a
    676▕ // lot more helpful to the developer instead of just the database’s errors.
    677▕ catch (Exception $e) {
    ➜ 678▕ throw new QueryException(
    679▕ $query, $this->prepareBindings($bindings), $e
    680▕ );
    681▕ }
    682▕

    1 C:\laragon\www\monblog\vendor\laravel\framework\src\Illuminate\Database\Connection.php:471
    PDOException::(« SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry ‘Category 1’ for key ‘categories_title_unique' »)

    2 C:\laragon\www\monblog\vendor\laravel\framework\src\Illuminate\Database\Connection.php:471
    PDOStatement::execute()

    Dans mes tables j’ai les utilisateurs et les 3 catégories; les tables tag, post, comment sont vides…

    Quand je me connecte, http://monblog.test/login. J’arrive à l’identification, j’ai choisi l’utilisateur id 2 et là j’arrive au dashbord de Laravel.

    Que dois je faire, svp ?

    Encore merci pour votre aide.

    • bestmomo

      Bonjour,

      Comme la population (seeder) impose des enregistrements, une fois que la base a été remplie de données si on veut refaire une population il faut rafraichir la base :
      php artisan migrate:fresh --seed
      En ce qui concerne la page qui s’affiche à l’issue du login pour le moment c’est la dashboard de Laravel, ça sera changé quand l’authentification adaptée au blog sera mise en place.

  • qanielutis

    Bonjour et merci pour tes formations ca m’aide enormement.
    J’ai un probleme au niveau UTILISATEURS (On va créer un administrateur, 2 rédacteurs et 3 utilisateurs de base 🙂
    J’aimerai savoir dans quel dossier(fichier) on insere les code? Je suis un peu embrouille a ce niveau.

      • webwatson

        Je l’avais mis vu que j’ai suivi toute les étapes.

        *Post.php*

        namespace App\Models;
        use Illuminate\Database\Eloquent\Model;
        use App\Events\ModelCreated;
        use Illuminate\Database\Eloquent\Factories\HasFactory;
        use Illuminate\Notifications\Notifiable;

        class Post extends Model
        {
        use HasFactory, Notifiable;

        *Comment.php*

        namespace App\Models;

        use Illuminate\Database\Eloquent\Model;
        use Kalnoy\Nestedset\NodeTrait;
        use Illuminate\Database\Eloquent\Factories\HasFactory;
        use Illuminate\Notifications\Notifiable;

        class Comment extends Model
        {
        use NodeTrait, HasFactory, Notifiable;

  • gil

    Hello,
    J’avais vu, mais je m’étais dit que c’était fait exprès pour que les lecteurs réfléchissent 🙂

    Non je blague, mais il est vrai que c’est un peu le problème des tutoriaux, on a tendance à ne faire que du copier-coller.
    Une idée d’ailleurs pourrait être de présenter des tutos en ayant en certains endroits des choses expendables-collapsable, cachées par défaut. Pas partout, mais parfois de dire « faites ceci », ou « créer ceci en en ajoutant 2 champs, un label ‘title’ et un booléen ‘valid’ « .
    (maintenant, c’est juste une idée)

    Et du coup (même si ça revient plutôt bien), je vais faire tes anciens tuto laravel 7 et , qui m’obligeront à réfléchir !

  • eric.lecathelinais@gmail.com

    Salut,

    Déjà merci pour ton blog sur laravel dans lequel j’apprends plein de chose

    Sinon juste une petite correction sur cette page
    php artisan migrate au lieu de php artisan:migrate

    Continue comme ça, c’est top 😉

Laisser un commentaire