1. One to One (Un à Un)
Migration
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('phones', function (Blueprint $table) {
$table->id();
$table->string('number');
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
});
Modèles
class User extends Model {
// ...
public function phone() {
return $this->hasOne(Phone::class);
}
}
class Phone extends Model {
// ...
public function user() {
return $this->belongsTo(User::class);
}
}
2. One to Many (Un à Plusieurs)
Migration
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
// ... autres colonnes
});
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('comment');
$table->unsignedBigInteger('post_id');
$table->foreign('post_id')->references('id')->on('posts');
});
Modèles
class Post extends Model {
// ...
public function comments() {
return $this->hasMany(Comment::class);
}
}
class Comment extends Model {
// ...
public function post() {
return $this->belongsTo(Post::class);
}
}
3. Many to Many (Plusieurs à Plusieurs)
Migration
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('courses', function (Blueprint $table) {
$table->id();
$table->string('title');
// ... autres colonnes
});
Schema::create('course_student', function (Blueprint $table) {
$table->unsignedBigInteger('course_id');
$table->unsignedBigInteger('student_id');
$table->primary(['course_id', 'student_id']);
$table->foreign('course_id')->references('id')->on('courses');
$table->foreign('student_id')->references('id')->on('students');
});
Modèles
class Student extends Model {
// ...
public function courses() {
return $this->belongsToMany(Course::class);
}
}
class Course extends Model {
// ...
public function students() {
return $this->belongsToMany(Student::class);
}
}
4. Has Many Through (A plusieurs à travers)
Migration
Schema::create('countries', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('states', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('country_id');
$table->foreign('country_id')->references('id')->on('countries');
// ... autres colonnes
});
Schema::create('cities', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('state_id');
$table->foreign('state_id')->references('id')->on('states');
// ... autres colonnes
});
Modèles
class Country extends Model {
// ...
public function cities() {
return $this->hasManyThrough(City::class, State::class);
}
}
class State extends Model {
// ...
public function cities() {
return $this->hasMany(City::class);
}
}
class City extends Model {
// ...
}
5. Polymorphic Relations (Relations polymorphes)
Migration
Schema::create('comments', function (Blueprint $table) {
$table->id();
$table->text('comment');
$table->unsignedBigInteger('commentable_id');
$table->string('commentable_type');
// ... autres colonnes
});
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
$table->text('content');
// ... autres colonnes
});
Schema::create('videos', function (Blueprint $table) {
$table->id();
$table->string('title');
// ... autres colonnes
});
Modèles
class Comment extends Model {
// ...
public function commentable() {
return $this->morphTo();
}
}
class Post extends Model {
// ...
public function comments() {
return $this->morphMany(Comment::class, 'commentable');
}
}
class Video extends Model {
// ...
public function comments() {
return $this->morphMany(Comment::class, 'commentable');
}
}
T
6. Many to Many Polymorphic (Plusieurs à Plusieurs Polymorphes)
Migration
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('taggables', function (Blueprint $table) {
$table->unsignedBigInteger('tag_id');
$table->unsignedBigInteger('taggable_id');
$table->string('taggable_type');
$table->primary(['tag_id', 'taggable_id', 'taggable_type']);
$table->foreign('tag_id')->references('id')->on('tags');
// ... autres colonnes
});
Modèles
class Tag extends Model {
// ...
public function posts() {
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos() {
return $this->morphedByMany(Video::class, 'taggable');
}
}
class Post extends Model {
// ...
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
}
class Video extends Model {
// ...
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
}
7. One to Many Polymorphic (Un à Plusieurs Polymorphes)
Migration
Schema::create('images', function (Blueprint $table) {
$table->id();
$table->string('url');
$table->unsignedBigInteger('imageable_id');
$table->string('imageable_type');
// ... autres colonnes
});
Modèles
class Image extends Model {
// ...
public function imageable() {
return $this->morphTo();
}
}
class Post extends Model {
// ...
public function images() {
return $this->morphMany(Image::class, 'imageable');
}
}
class Video extends Model {
// ...
public function images() {
return $this->morphMany(Image::class, 'imageable');
}
}
8. Has One Through (A un à travers)
Migration
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('profiles', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('address');
$table->string('phone');
$table->foreign('user_id')->references('id')->on('users');
// ... autres colonnes
});
Schema::create('photos', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('profile_id');
$table->string('url');
$table->foreign('profile_id')->references('id')->on('profiles');
// ... autres colonnes
});
Modèles
class User extends Model {
// ...
public function photo() {
return $this->hasOneThrough(Photo::class, Profile::class);
}
}
class Profile extends Model {
// ...
public function user() {
return $this->belongsTo(User::class);
}
public function photo() {
return $this->hasOne(Photo::class);
}
}
class Photo extends Model {
// ...
public function profile() {
return $this->belongsTo(Profile::class);
}
}
9. Local Scopes (Portées locales)
Modèle
class Post extends Model {
// ...
public function scopePublished($query) {
return $query->where('published', true);
}
}
// Utilisation
$publishedPosts = Post::published()->get();
10. Global Scopes (Portées globales)
Vous pouvez également définir des portées globales qui sont automatiquement appliquées à toutes les requêtes pour ce modèle :
Modèle
class User extends Model {
// ...
protected static function boot() {
parent::boot();
static::addGlobalScope('active', function (Builder $builder) {
$builder->where('active', true);
});
}
}
// Utilisation
$activeUsers = User::all(); // Seulement les utilisateurs actifs seront récupérés
11. Relations personnalisées
Migration
Schema::create('orders', function (Blueprint $table) {
$table->id();
$table->string('order_number');
// ... autres colonnes
});
Schema::create('order_items', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('order_id');
$table->string('product_name');
// ... autres colonnes
$table->foreign('order_id')->references('id')->on('orders');
});
Modèles
class Order extends Model {
// ...
public function items() {
return $this->hasMany(OrderItem::class);
}
public function expensiveItems() {
return $this->hasMany(OrderItem::class)
->where('price', '>', 100);
}
}
class OrderItem extends Model {
// ...
public function order() {
return $this->belongsTo(Order::class);
}
}
12. Soft Deletes
Laravel prend en charge les suppressions douces (soft deletes), ce qui signifie que vous pouvez "supprimer" un enregistrement sans le supprimer physiquement de la base de données. Voici comment vous pouvez le mettre en œuvre :
Migration
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->softDeletes(); // Ajout de la colonne pour la suppression douce
// ... autres colonnes
});
Modèle
use Illuminate\Database\Eloquent\SoftDeletes;
class Product extends Model {
use SoftDeletes; // Utilisation de la suppression douce
// ...
}
Avec la suppression douce activée, vous pouvez récupérer des enregistrements supprimés à l'aide de la méthode withTrashed().
13. Timestamps
Laravel crée automatiquement des colonnes created_at et updated_at pour chaque modèle, mais vous pouvez également ajouter des colonnes de date personnalisées si nécessaire.
Migration
Schema::create('events', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamp('start_date');
$table->timestamp('end_date');
// ... autres colonnes
});
Modèle
class Event extends Model {
// ...
}
Ces exemples introduisent des concepts supplémentaires tels que les relations personnalisées, les suppressions douces (soft deletes), et les timestamps dans Laravel. N'oubliez pas d'ajuster ces exemples en fonction de vos besoins spécifiques.
14. Enumérations (Enums)
Bien que Laravel ne dispose pas nativement d'un type ENUM, vous pouvez simuler des ENUM en utilisant des constantes dans une classe ou un trait.
Exemple d'Enum (dans un trait)
trait StatusEnum {
public static $STATUS_PENDING = 'pending';
public static $STATUS_APPROVED = 'approved';
public static $STATUS_REJECTED = 'rejected';
}
Modèle utilisant l'Enum
class Post extends Model {
use StatusEnum;
// ...
public function scopeApproved($query) {
return $query->where('status', self::$STATUS_APPROVED);
}
}
// Utilisation
$approvedPosts = Post::approved()->get();
15. Indexation et Contraintes
Lorsque vous créez des migrations, vous pouvez également spécifier des index pour optimiser les performances des requêtes sur certaines colonnes.
Migration avec Index
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('email')->unique(); // Index unique
$table->string('username');
$table->index(['username', 'email']); // Index composite
// ... autres colonnes
});
16. Validation au niveau du modèle
Vous pouvez également définir des règles de validation directement au niveau du modèle pour garantir la validité des données.
Modèle avec Validation
class User extends Model {
// ...
public static $rules = [
'name' => 'required|string',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
];
public static function validate(array $data) {
return Validator::make($data, self::$rules);
}
}
// Utilisation
$data = [
'name' => 'John Doe',
'email' => 'john@example.com',
'password' => 'secret123',
];
$validator = User::validate($data);
if ($validator->fails()) {
// Gérer les erreurs de validation
}
17. Événements de modèle
Laravel permet de définir des événements au niveau du modèle qui sont déclenchés lors de certaines actions, tels que la création, la mise à jour, et la suppression d'un modèle.
Modèle avec Événements
class Post extends Model {
// ...
protected $dispatchesEvents = [
'created' => PostCreated::class,
'updated' => PostUpdated::class,
'deleted' => PostDeleted::class,
];
}
18. Factory et Seeders
Lorsque vous travaillez avec des jeux de données de test, les factories et les seeders de Laravel sont des outils puissants pour générer des données fictives.
Factory
use Illuminate\Database\Eloquent\Factories\Factory;
class UserFactory extends Factory {
protected $model = User::class;
public function definition() {
return [
'name' => $this->faker->name,
'email' => $this->faker->unique()->safeEmail,
'password' => bcrypt('password'),
];
}
}
Seeder
class DatabaseSeeder extends Seeder {
public function run() {
\App\Models\User::factory(10)->create();
// ... autres factories
}
}
Ces exemples introduisent des concepts supplémentaires tels que les Enums, les index, la validation au niveau du modèle, les événements de modèle, et l'utilisation des factories et seeders dans Laravel. N'oubliez pas d'ajuster ces exemples en fonction de vos besoins spécifiques.
19. Relations polymorphes many-to-many
Migration
Schema::create('tags', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('taggables', function (Blueprint $table) {
$table->unsignedBigInteger('tag_id');
$table->unsignedBigInteger('taggable_id');
$table->string('taggable_type');
$table->primary(['tag_id', 'taggable_id', 'taggable_type']);
$table->foreign('tag_id')->references('id')->on('tags');
// ... autres colonnes
});
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->string('title');
// ... autres colonnes
});
Schema::create('videos', function (Blueprint $table) {
$table->id();
$table->string('title');
// ... autres colonnes
});
Modèles
class Tag extends Model {
// ...
public function posts() {
return $this->morphedByMany(Post::class, 'taggable');
}
public function videos() {
return $this->morphedByMany(Video::class, 'taggable');
}
}
class Post extends Model {
// ...
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
}
class Video extends Model {
// ...
public function tags() {
return $this->morphToMany(Tag::class, 'taggable');
}
}
20. Relations Many to Many avec colonnes supplémentaires (Pivot avec attributs)
Migration
Schema::create('students', function (Blueprint $table) {
$table->id();
$table->string('name');
// ... autres colonnes
});
Schema::create('courses', function (Blueprint $table) {
$table->id();
$table->string('title');
// ... autres colonnes
});
Schema::create('course_student', function (Blueprint $table) {
$table->unsignedBigInteger('course_id');
$table->unsignedBigInteger('student_id');
$table->boolean('is_enrolled')->default(false);
$table->foreign('course_id')->references('id')->on('courses');
$table->foreign('student_id')->references('id')->on('students');
});
Modèles
class Student extends Model {
// ...
public function courses() {
return $this->belongsToMany(Course::class)->withPivot('is_enrolled');
}
}
class Course extends Model {
// ...
public function students() {
return $this->belongsToMany(Student::class)->withPivot('is_enrolled');
}
}