У меня есть собственный проект разработки, в котором есть таблицы базы данных:
- пользователи
- кандидаты
- компании
- объемы
- навыки и умения
Таблица пользователей:
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('nickname')->unique();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->boolean('type')->default(0); // 0 = candidate and 1 = company
$table->rememberToken();
$table->timestamps();
});
Таблица кандидатов:
Schema::create('candidates', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->string('name')->nullable();
$table->string('lastname')->nullable();
$table->string('surname')->nullable();
$table->text('about')->nullable();
$table->timestamps();
});
Таблица компаний:
Schema::create('companies', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->unsignedInteger('logo');
$table->foreign('logo')
->references('id')
->on('images')
->onDelete('cascade');
$table->string('name')->nullable();
$table->text('about')->nullable();
$table->string('website')->nullable();
$table->integer('employees')->nullable();
$table->timestamps();
});
Таблица областей действия:
Schema::create('scopes', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Таблица навыков:
Schema::create('skills', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Здесь у любого типа пользователей есть возможности и навыки. Я могу решить это решение, создав одну таблицу:
Таблица атрибутов:
Schema::create('attributes', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->morphs('model');
$table->timestamps();
});
Пример данных в таблице атрибутов:
----------------------------------------
| id | user_id | model_id | model_type |
----------------------------------------
| 15 | 176 | 34458 | App\Scope |
----------------------------------------
| 29 | 245 | 17654 | App\Skill |
----------------------------------------
Но в этом решении для меня есть одна плохая сторона, это повторение строкового имени модели в каждой строке записи в таблице. Например:
Таблица моделей:
Schema::create('models', function (Blueprint $table) {
$table->increments('id');
$table->string('name')->unique();
$table->timestamps();
});
Примечание. Может оказаться невозможным создать модуль с именем Модель, поэтому вам может потребоваться создать его с другим именем, например: Ссылка
Пример данных в таблице models:
-------------------
| id | name |
-------------------
| 10 | App\Scope |
-------------------
| 11 | App\Skill |
-------------------
После создания таблицы моделей структура таблицы атрибутов изменится на:
Таблица атрибутов:
Schema::create('attributes', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->foreign('user_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->foreign('model_id')
->references('id')
->on('models')
->onDelete('cascade');
$table->unsignedInteger('content_id');
$table->timestamps();
});
Теперь, как я могу создать правильные отношения внутри моделей, чтобы получить у кандидатов или компании навыки работы с типами пользователей или их объем?
У меня есть собственные отношения внутри модели пользователей:
public function candidate()
{
return $this->hasOne(Candidate::class);
}
public function company()
{
return $this->hasOne(Company::class);
}
Теперь мне нужны такие отношения внутри кандидата и компании:
public function skills()
{
// Some code here
}
public function scopes()
{
// Some code here
}
Как правило, получайте навыки или возможности пользователей следующим образом:
$user->candidate->scopes
$user->company->skills
Если у вас есть другое предложение по решению моей проблемы, пожалуйста, предложите свое предложение. Если где-то ошибся, поправьте меня, если можно.