introduction
Parlons de l'utilisation possible des traits ainsi que des relations polymorphes dans Laravel.
Le contenu de l'article:
- Description du domaine
- Création d'application
- Structures de base de données possibles
- Création d'entité
- Utilisation des traits
- Tests d'écriture
Description du domaine
Nous développerons un système dans lequel certains employés et certaines équipes pourront être rattachés au projet. L'essence du sujet sera les employés, les équipes et les projets: une équipe composée d'employés, d'employés et d'équipes peut être attachée à un projet. Entre une équipe et un employé, une relation plusieurs à plusieurs (disons qu'un employé peut participer à différentes équipes), plusieurs à plusieurs entre projets et employés, plusieurs à plusieurs entre équipes et projets. Pour un examen plus approfondi, omettons la mise en œuvre de la communication entre l'équipe et les employés, concentrons-nous sur l'attitude des équipes et des employés envers le projet.
Création d'application
Les applications Laravel sont très faciles à construire à l' aide du package du créateur d'application . Après l'avoir installé, la création d'une nouvelle application tient dans une seule commande:
laravel new system
Structures de base de données possibles
, : -, -, -.
, - - , (, 1 — , 2 — ).
- , — , .
, , , . :
php artisan make:model Employee -f //
php artisan make:model Team -f //
php artisan make:model Project -f //
php artisan make:migration CreateEntitiesTables //
php artisan make:model Attach -m //
App/, database/migrations/ database/factories/.
. , : , . — .
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateEntitesTables extends Migration
{
public function up()
{
Schema::create('employees', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('teams', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
Schema::create('projects', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('employees');
Schema::dropIfExists('teams');
Schema::dropIfExists('projects');
}
}
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateAttachesTable extends Migration
{
public function up()
{
Schema::create('attachments', function (Blueprint $table) {
$table->id();
$table->morphs('attachable');
$table->unsignedInteger('project_id');
$table->timestamps();
$table->foreign('project_id')->references('id')->on('projects')
->onDelete('cascade');
});
}
public function down()
{
Schema::dropIfExists('attachments');
}
}
, morphs().
:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Employee extends Model
{
protected $fillable = ['name'];
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Team extends Model
{
protected $fillable = ['name'];
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
class Project extends Model
{
protected $fillable = ['name'];
public function attachments()
{
return $this->hasMany(Attach::class);
}
public function employees()
{
return $this->morphedByMany(Employee::class, 'attachable', 'attachments');
}
public function teams()
{
return $this->morphedByMany(Team::class, 'attachable', 'attachments');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Attach extends Model
{
protected $table = 'attachments';
protected $fillable = ['attachable_id', 'attachable_type', 'project_id'];
}
<?php
use Faker\Generator as Faker;
$factory->define(, function (Faker $faker) {
return [
'name' => $faker->colorName
];
});
, .
Laravel — morphedByMany(), — morphToMany(). , .
app/Traits : Attachable.php
<?php
namespace App\Traits;
use App\Project;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
trait Attachable
{
public function attachments()
{
return $this->morphToMany(Project::class, 'attachable', 'attachments');
}
}
use.
...
use Attachable;
...
.
, Laravel PHPUnit . :
php artisan make:test AttachableTest
tests/Feature/. RefreshDatabase.
Vérifiez la morphologie du côté du projet et le trait de la part de l'équipe et du personnel
<?php
namespace Tests\Feature;
use App\Team;
use App\Employee;
use App\Project;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
class OrderTest extends TestCase
{
use RefreshDatabase;
public function polymorphic_relations_scheme(): void
{
$project = factory(Project::class)->create();
$team = factory(Team::class)->create();
$employee = factory(Employee::class)->create();
$project->teams()->save($team);
$project->employees()->save($employee);
$this->assertCount(2, $project->attachments);
$this->assertCount(1, $project->teams);
$this->assertCount(1, $project->employees);
$this->assertEquals($team->id, $project->teams->first()->id);
$this->assertEquals($employee->id, $project->employees->first()->id);
$this->assertCount(1, $team->attachments);
$this->assertCount(1, $employee->attachments);
$this->assertEquals($project->id, $team->attachments->first()->id);
$this->assertEquals($project->id, $employee->attachments->first()->id);
}
}
Le test est réussi!
Les traits vous permettent de ne pas dupliquer les méthodes courantes pour les relations polymorphes au sein des classes de modèle, vous pouvez également les utiliser si vous avez les mêmes champs dans de nombreuses tables (par exemple, l'auteur de l'enregistrement) - ici, vous pouvez également faire un trait avec la méthode de connexion.
Je serai heureux d'entendre vos cas d'utilisation de traits dans Laravel et PHP.