Structure de la base de données
Pour un système de blog simple, nous avons besoin d’au moins 4 tables de base de données : Users
, Categories
, Tags
et Posts
. Si vous voulez d’autres fonctions pour votre blog, des commentaires, par exemple, vous pouvez ajouter d’autres tables vous-même. Pour que ce tutoriel soit court et facile à comprendre, ces quatre tableaux sont tout ce dont nous avons besoin.
Table des utilisateurs "Users"
id | integer | auto increment |
name | string | not null |
string | unique, not null | |
password | string |
Table des catégories "Categories"
name | string | not null |
slug | string | unique, not null |
description | text | not null |
Table des étiquettes "Tags"
name | string | not null |
slug | string | unique, not null |
description | text | not null |
Table des articles "Posts"
title | string | not null |
slug | string | unique, not null |
featured image | string | not null |
content | text | not null |
published | boolean | |
featured | boolean |
Relations
Un à un (One to One)
Il s’agit de la relation la plus élémentaire. Par exemple, chaqueUser
est associé à un Phone
. Pour définir cette relation, nous devons créer une fonction phone
sur l’objet User
qui contiendra la relation vers Phone.
class User extends Model
{
public function phone()
{
return $this->hasOne('App\Phone');
}
}
L’inverse de “hasOne” est “belongsTo”. Par exemple, chaque Phone
appartiens à un User
. Afin de définir l’inverse de la relation One to One. Nous plaçons un user
sur l’objet Phone
.
class Phone extends Model
{
public function user()
{
return $this->belongsTo('App\User');
}
}
De un à plusieurs ( One to Many )
Une relation de type “un à plusieurs” est utilisée pour définir des relations où un seul modèle possède un nombre quelconque d’autres modèles. Par exemple, unCategory
peut avoir plusieurs Post
s. Tout comme la relation un à un, elle peut être définie en mettant une méthode posts
dans l’objet Category
.
class Category extends Model
{
public function posts()
{
return $this->hasMany('App\Post');
}
}
Cependant, il est parfois nécessaire de trouver la catégorie par le biais du poste. L’inverse de “One to Many” est “belongsTo” également.
class Post extends Model
{
public function category()
{
return $this->belongsTo('App\Category');
}
}
Plusieurs à plusieurs ( Many to Many )
Les relations « Plusieurs à plusieurs » sont légèrement plus compliquées que les relations entre plusieurs modèles.hasOne
et hasMany
. Un exemple d’une telle relation est qu’un article a plusieurs étiquettes et chaque étiquette appartient à plusieurs articles. Nous en parlerons plus tard.
Relations de conception
Pour notre projet de site web de blog. Il y a six relations dont nous devons nous occuper.
- Chaque utilisateur a plusieurs articles
- Chaque catégorie a plusieurs articles
- Chaque étiquette appartient à plusieurs articles
- Chaque article appartient à un utilisateur
- Chaque article appartient à une catégorie
- Chaque article appartient à plusieurs tags
Créer des modèles
Maintenant, il est temps pour nous de mettre en œuvre cette conception. La première chose à faire est de générer les modèles et les fichiers de migration nécessaires à notre projet à l’aide des commandes artisanales.
php artisan make:model Category -m
php artisan make:model Post -m
php artisan make:model Tag -m
Modèle des catégories
database/migrations/
{date_de_creation}_create_categories_table.php
public function up()
{
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
Ligne 6, unique()
signifie que chaque enregistrement de la colonne slug
est unique.
Ligne 7, nullable()
signifie que l’enregistrement dans la colonne peut être vide.
Ligne 8, timestamps()
crée deux colonnes qui stockent le moment où l’enregistrement est créé « created_at » et celui où il est mis à jour « updated_at ».
app/Models/Category.php
class Category extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'description',
'slug',
];
}
Modèle des étiquettes
database/migrations/{date_de_creation}_create_tags_table.php
public function up()
{
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
}
app/Models/Tag.php
class Tag extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'description',
'slug',
];
}
Modèle des articles
database/migrations/{date_de_creation}_create_posts_table.php
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->bigInteger('category_id');
$table->bigInteger('user_id');
$table->string('title');
$table->string('slug')->unique();
$table->text('content');
$table->string('featured_image')->nullable();
$table->boolean('is_featured')->default(false);
$table->boolean('is_published')->default(false);
$table->timestamps();
});
}
app/Models/Post.php
class Post extends Model
{
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'category_id',
'user_id',
"title",
'content',
'slug',
'featured_image',
'is_featured',
'is_published'
];
}
Relationship
Entre l’utilisateur et le poste (un à plusieurs)
Si vous avez suivi la section précédente, nous avons déjà ajouté une fonction user_id
dans le fichier posts
tableau.
database/migrations/create_posts_table.php
$table->bigInteger('user_id');
Cette colonne stocke l’identifiant de l’utilisateur à qui appartient l’article. Maintenant nous pouvons définir les relations dans les modèles. N’oubliez pas le nouveau répertoire indépendant pour les modèles !
app/Models/User.php
/**
* Get the posts for the user.
*/
public function posts()
{
return $this->hasMany('App\Models\Post');
}
app/Models/Post.php
/**
* Get the user that owns the post.
*/
public function user()
{
return $this->belongsTo('App\Models\User');
}
Entre la catégorie et l’article (un à plusieurs)
Encore une fois, nous devons avoir un category_id
dans le fichier posts
qui stocke l’identifiant de la catégorie dans laquelle se trouve ce message.
database/migrations/{date_de_creation}_create_posts_table.php
$table->bigInteger('category_id');
Définir les relations dans les modèles.
app/Models/Category.php
/**
* Get the posts for the user.
*/
public function posts()
{
return $this->hasMany('App\Models\Post');
}
app/Models/Post.php
:
/**
* Get the category that owns the post.
*/
public function category()
{
return $this->belongsTo('App\Models\Category');
}
Entre les étiquettes et les articles (Many to Many)
Celle-ci est un peu plus compliquée, elle nécessite une fonction Relation de plusieurs à plusieurs et une table de base de données supplémentaire post_tag
. Ce tableau est appelé tableau croisé dynamique.
Tout d’abord, créez un nouveau fichier de migration :
php artisan make:migration create_post_tag_table
database/migrations/create_post_tag_table.php
Schema::create('post_tag', function (Blueprint $table) {
$table->bigInteger('tag_id');
$table->bigInteger('post_id');
});
Maintenant nous pouvons définir les relations entre les tags et les posts.
app/Models/Tag.php
public function posts()
{
return $this->belongsToMany('App\Models\Post');
}
app/Models/Post.php
public function tags()
{
return $this->belongsToMany('App\Models\Tag');
}
Ici, Laravel suppose qu’il existe un post_tag
et qu’il y a deux colonnes post_id
et tag_id
dans le tableau. Le nom de la table doit être dans l’ordre alphabétique. Si vous les avez nommés différemment, tag_post
par exemple, vous devez les spécifier comme suit.
public function tags()
{
return $this->belongsToMany('App\Models\Tag', 'tag_post');
}
N’oubliez pas d’appliquer les fichiers de migration en utilisant php artisan migrate
.
Voyager
Pour configurer Voyager, nous n’avons pas besoin d’écrire de code. Tout ce que nous devons faire est d’ajouter BREAD (browse, read, edit, add and delete) pour chaque table de la base de données (à l’exclusion de post_tag
).
Aller dans Tools->BREAD :
Modifier le BREAD pour categories
Tout d’abord, nous devons nous assurer que Voyager peut trouver le modèle correspondant. Dans la section “Categories BREAD info”, trouvez le “Model Name”, et changez-le en App\Models\Category
soit le namespace de la classe du même nom Category.php.
Après cela, faites défiler vers le bas jusqu’à la section suivante, et changez le type de saisie pour “description” en “zone de texte”. Vous obtiendrez ainsi une zone de texte plus grande pour la description. N’oubliez pas d’enregistrer les modifications avant de poursuivre.
Nous devons également ajouter la relation dans Voyager, comme nous l’avons conçu, chaque catégorie a beaucoup de postes :
Modifier le BREAD pour tags
Faites la même chose pour les tags.
Ajouter des relations :
Note : Vous allez devoir créer un override pour corriger un bug dans voyager public/resources/views/vendor/voyager/formfields/relationship.blade.php
en copiant-collant le code à partir du fichiervendor/tcg/voyager/resources/views/formfields/relationship.blade.php
et remplacer la ligne 163
data-route="{{ route('voyager.'.\Illuminate\Support\Str::slug($options->table).'.store') }}"
par
data-route="{{ route('voyager.'.\Illuminate\Support\Str::slug($dataType->slug).'.store') }}"
Pourquoi ? Voyager utilise le nom de la table au lieu du slug pour rechercher une route, nous avons modifier le slug de la table Posts par blog-post pour éviter un conflit avec les routes par défaut de Voyager, hors si on créer une relations Belongs To Many vers Post avec « Allow Tagging » d’activer, Voyager essayera de trouver la route voyager.posts.store à la place voyager.blog-posts.store.
Si vous voulez voir la listes des routes possibles, vous pouvez taper la commande suivante :
php artisan route:list
Modifier le BREAD pour posts
Ajouter des relations :
Modifier le BREAD pour users
Nous devons seulement ajouter une relation supplémentaire pour les utilisateurs et les messages :
Maintenant, vous devriez pouvoir voir les éléments de menu “Categories”, “Tags” et “Posts”.
Erreur lors de la modification des messages
Cette erreur est due au fait que Voyager possède déjà un Post
intégré, et le Post
que nous avons créé est en conflit avec lui.
Pour résoudre ce problème, nous changeons l’URL Slug des articles en quelque chose d’autre que posts
. Rendez-vous dans BREAD -> Posts -> Edit -> Url Slug
Ensuite, allez dans Menu Builder et éditer le menu admin -> posts pour indiquer le lien en static :
Tutoriel Laravel 9
Newsletter
Ne manquez jamais les nouveaux conseils, tutoriels et autres.
Pas de spam, jamais. Nous ne partagerons jamais votre adresse électronique et vous pouvez vous désabonner à tout moment.