اخیراً به هوتن تسکی داده شده که باید دیتابیسی پر از جدول با روابط متعدد ایجاد کند. او که از این کار خسته شده، ایدهای به ذهنش رسیده که این فرایند را خودکار کند. برای این کار به هوتن کمک کنید.
# جزئیات پروژه
پروژهی اولیه را از [این لینک](/contest/assignments/35048/download_problem_initial_project/124279/) دانلود کنید.
<details class="grey">
<summary>ساختار فایلها</summary>
```
model-maker
├── app
├── bootstrap
├── config
├── database
├── public
├── resources
├── routes
├── storage
├── tests
├── README.md
├── artisan
├── composer.json
├── composer.lock
├── package.json
├── phpunit.xml
├── server.php
└── webpack.mix.js
```
</details>
<details class="brown">
<summary>راهاندازی پروژه</summary>
**برای اجرای پروژه، باید `php` و `composer` را از قبل نصب کرده باشید.**
+ ابتدا پروژهی اولیه را دانلود و از حالت فشرده خارج کنید.
+ دستور `composer install` را در پوشهی اصلی پروژه برای نصب نیازمندیها اجرا کنید.
+ برای اجرای تستهای نمونه، میتوانید از دستور `php artisan test` استفاده کنید.
</details>
شما باید دستوری را ایجاد کنید تا مدلها و مایگریشنهایی را با جزئیاتی که در ادامه گفته میشود، ایجاد کند.
قالب دستوری که میسازید باید بهصورت زیر باشد:
```shell
php artisan make:custom-model <mark title="نام مدل اول">MODEL_NAME_1</mark> <mark title="نام مدل دوم">MODEL_NAME_2</mark> --type=<mark title="نوع رابطه">RELATION_TYPE</mark>
```
دستور فوق به این معنی است که باید دو مدل با نامهای `MODEL_NAME_1` و `MODEL_NAME_2` ایجاد شوند و بین این دو مدل رابطهای از نوع `RELATION_TYPE` برقرار شود. مقدار `RELATION_TYPE` میتواند یکی از مقادیر `11`، `1n` یا `nn` باشد. `11` بهمعنی رابطهی *One to One* ، `1n` بهمعنی رابطهی *One to Many* و `nn` بهمعنی رابطهی *Many to Many* است.
## مثال
فرض کنید دستور زیر اجرا میشود:
```shell
php artisan make:custom-model <mark title="نام مدل اول">Author</mark> <mark title="نام مدل دوم">Book</mark> --type=<mark title="نوع رابطه">nn</mark>
```
با اجرای دستور فوق، باید فایلهای `Author.php` و `Book.php` در دایرکتوری `app/Models` ایجاد شوند. محتویات فایلهای این دو کلاس باید بهصورت زیر باشد:
<details class="red">
<summary>محتویات مدلها</summary>
```php app/Models/Author.php laravel
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Author extends Model
{
use HasFactory;
public function books()
{
return $this->belongsToMany(Book::class);
}
}
```
```php app/Models/Book.php laravel
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Book extends Model
{
use HasFactory;
public function authors()
{
return $this->belongsToMany(Author::class);
}
}
```
</details>
همچنین مایگرشنهای مورنیاز مدلها و رابطهشان باید ایجاد شود:
<details class="red">
<summary>محتویات مایگریشنها</summary>
```php database/migrations/2021_11_16_202919_create_authors_table.php laravel
class CreateAuthorsTable extends Migration
{
public function up()
{
Schema::create('authors', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('authors');
}
}
```
```php database/migrations/2021_11_16_202921_create_books_table.php laravel
class CreateBooksTable extends Migration
{
public function up()
{
Schema::create('books', function (Blueprint $table) {
$table->id();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('books');
}
}
```
```php database/migrations/2021_11_16_202922_create_author_book_table.php laravel
class CreateAuthorBookTable extends Migration
{
public function up()
{
Schema::create('author_book', function (Blueprint $table) {
$table->id();
$table->foreignId('author_id')->constrained()->onDelete('cascade');
$table->foreignId('book_id')->constrained()->onDelete('cascade');
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('author_book');
}
}
```
</details>
نکتهی مهمی که باید به آن دقت کنید نام روابط در مدلهاست، که باید بهصورت زیر قرار دهید:
+ اگر نوع رابطه مفرد به مفرد بود نام رابطه باید بهصورت مفرد کلاس هدف قرار گیرد مثلا فرض کنید بین دو مدل `User` و `Name` رابطه یکبهیک برقرار است پس نام رابطه در مدل `User` باید برابر `name` قرار گیرد.
+ اگر نوع رابطه مفرد به جمع بود نام رابطه باید بهصورت جمع کلاس هدف قرار گیرد مثل مدلهای `Author` و `Book` مثال ذکر شده در همین سوال.
**تضمین میشود** که در دستور نام مدلها بهصورت صحیح داده میشوند.
# نکات
+ برای هر رابطه باید مدل و مایگریشن متناسب با **نوع رابطه** ایجاد شود.
+ در نامگذاری جداول، باید از ***convention* لاراول** پیروی کنید.
+ تمامی این فرایندها باید بهصورت خودکار انجام شود و در داوری، ساخت مدلهای مختلف تست میشود.
+ برای ساخت مایگریشنها حتماً به زمان ساخت مایگریشنها دقت کنید تا بهترتیب اجرا شوند.
+ شما تنها مجاز به اعمال تغییرات در پوشه `app` و در صورت نیاز `stubs` هستید.
# آنچه باید آپلود کنید
پس از پیادهسازی موارد خواستهشده، پوشهی `app` و پوشهی `stubs` را (در صورت وجود) زیپ کرده و آپلود کنید.