المقدمة
لنتحدث عن الاستخدام المحتمل للسمات جنبًا إلى جنب مع العلاقات متعددة الأشكال في Laravel.
محتوى المقالة:
- وصف المجال
- إنشاء التطبيق
- هياكل قاعدة البيانات الممكنة
- إنشاء الكيان
- استخدام السمات
- اختبارات الكتابة
وصف المجال
سنضع نظامًا يمكن فيه إلحاق بعض الموظفين وفرق معينة بالمشروع. سيكون جوهر الموضوع هو الموظفين والفرق والمشاريع: يتكون الفريق من الموظفين والموظفين والفرق ويمكن إرفاقه بالمشروع. بين فريق وموظف ، علاقة أطراف بأطراف (دعنا نقول أنه يمكن لموظف المشاركة في فرق مختلفة) ، بين أطراف وأخرى بين المشاريع والموظفين ، والعديد من بين الفرق والمشاريع. لمزيد من الدراسة ، دعنا نحذف تنفيذ التواصل بين الفريق والموظفين ، ونركز على موقف الفرق والموظفين تجاه المشروع.
إنشاء التطبيق
من السهل جدًا إنشاء تطبيقات Laravel باستخدام حزمة صانع التطبيقات . بعد تثبيته ، يتناسب إنشاء تطبيق جديد مع أمر واحد:
laravel new system
هياكل قاعدة البيانات الممكنة
, : -, -, -.
, - - , (, 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.
تحقق من الشكل على جانب المشروع والسمات من جانب الفريق والموظفين
<?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);
}
}
لقد مر الاختبار!
تسمح لك السمات بعدم تكرار الطرق الشائعة للعلاقات متعددة الأشكال داخل فئات النموذج ، يمكنك أيضًا استخدامها إذا كان لديك نفس الحقول في العديد من الجداول (على سبيل المثال ، مؤلف السجل) - هنا يمكنك أيضًا إنشاء سمة باستخدام طريقة الاتصال.
سأكون سعيدًا لسماع حالاتك المتعلقة باستخدام السمات في Laravel و PHP.