我有开发自定义项目,其中有数据库表:
用户表:
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();
});
attributes表中的示例数据:
----------------------------------------
| 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();
});
注意:可能无法使用模型的名称创建模块,因此您可能需要使用其他名称创建它,例如:Reference
models表中的示例数据:
-------------------
| id | name |
-------------------
| 10 | App\Scope |
-------------------
| 11 | App\Skill |
-------------------
创建models表格后,attribute表格的结构更改为:
属性表:
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
如果你对解决我的问题还有什么建议,请提出来。如果我在什么地方犯了错,如果可能的话,请纠正我。
发布于 2018-10-22 01:29:29
我认为您的主要ORM构造错误在下面这一行中:
$table->boolean('type')->default(0); // 0 = candidate and 1 = company
这不是使用Laravel的ORM可以解决的。您必须将此行替换为
$table->unsignedInteger('candidate_id')->nullable()->index();
$table->unsignedInteger('company_id')->nullable()->index();
然后从那里开始。因为它既可以是候选人,也可以是公司,其中一个值将为空。很容易检查。由于只有两种可能的选择,因此并不真正需要多态关系。一旦你通过了检查,你的ORM层次结构就会勾勒出它自己的轮廓。
你只需要注意,如果一个候选人成为一家公司,或者反之亦然,你需要确保其他的值被作废。这一切都可以在Model的赋值器或个性化的公共函数中完成,因此您不必在控制器/视图中担心它。
例如,在其中添加用户模型函数getChoiceAttribute()
的$user->choice->scopes;
public function getChoiceAttribute() {
if ($this->candidate) {
return $this->candidate;
}
if ($this->company) {
return $this->company;
}
return null;
}
这同样适用于设置器函数setChoiceAttribute()
,以防候选人成为一家公司。这仅适用于您保存或更新记录的情况。
要在视图中了解您是否在与候选人或公司合作,只需查看$user->choice->getTable();
。
https://stackoverflow.com/questions/52912368
复制相似问题