pengantar
Mari kita bicara tentang kemungkinan penggunaan sifat bersama dengan hubungan polimorfik di Laravel.
Isi artikel:
- Deskripsi Domain
- Pembuatan aplikasi
- Struktur database yang mungkin
- Penciptaan Entitas
- Penggunaan Karakter
- Tes menulis
Deskripsi Domain
Kami akan mengembangkan sistem di mana beberapa karyawan dan tim tertentu dapat dilampirkan ke proyek. Inti dari area subjek adalah karyawan, tim, dan proyek: tim yang terdiri dari karyawan, karyawan, dan tim dapat dilampirkan ke proyek. Antara tim dan karyawan, hubungan banyak-ke-banyak (misalkan karyawan dapat berpartisipasi dalam tim yang berbeda), banyak-ke-banyak antara proyek dan karyawan, banyak-ke-banyak antara tim dan proyek. Untuk pertimbangan lebih lanjut, mari kita lupakan implementasi komunikasi antara tim dan karyawan, fokus pada sikap tim dan karyawan terhadap proyek.
Pembuatan aplikasi
Aplikasi Laravel sangat mudah dibangun menggunakan paket pembuat aplikasi . Setelah menginstalnya, membuat aplikasi baru sesuai dengan satu perintah:
laravel new system
Struktur database yang mungkin
, : -, -, -.
, - - , (, 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.
Periksa morf di sisi proyek dan sifat pada bagian tim dan staf
<?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);
}
}
Tes telah berlalu!
Ciri memungkinkan Anda untuk tidak menduplikasi metode umum untuk hubungan polimorfik dalam kelas model, Anda juga dapat menggunakannya jika Anda memiliki bidang yang sama di banyak tabel (misalnya, penulis catatan) - di sini Anda juga dapat membuat ciri dengan metode koneksi.
Saya akan senang mendengar kasus Anda menggunakan ciri-ciri dalam Laravel dan PHP.