Laravel 与自定义枢轴的多态关系 Table
Laravel Polymorphic Relationship with Custom Pivot Table
我有以下
Schema::create('bursary_providers', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('bursary_provider',64);
$table->timestamps();
});
Schema::create('bursary_provider_contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->integer('bursary_provider_id')->unsigned()->index();
$table->foreign('bursary_provider_id')->references('id')->on('bursary_providers')->onDelete('cascade');
$table->integer('contact_id')->unsigned()->index();
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$table->timestamps();
});
Schema::create('contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('contact_name', 32);
$table->timestamps();
});
1) 是的,我知道这不符合存储 'type' 的典型惯例。我这样做是为了参照完整性。
2) 我将它存储在一个自定义的名为 pivot table 中,因为它对我来说更有意义。 Laravels pivot table 要求是按字母顺序排列,但让我们保持这样,因为我希望命名为 parent_child
现在,我该如何设置我的模型?根据我的理解,这种情况将是一个 morphMany(除了 'bursary_providers' 之外还有其他 parents - 为了避免混淆而省略)。所以我会在我的 BursaryProvider 模型中使用以下内容:
public function contacts() {
return $this->morphMany('App\Contact');
}
以及我的联系人模型中的以下内容:
public function bursary_provider () {
return $this->morphTo();
}
如何更改以上内容,以便它们使用 bursary_providers.id / contacts.id 和枢轴 table bursary_provider_contacts(bursary_provider_id 和 contact_id )?
// 编辑
为了清楚起见,另一个'parent'而不是bursary_providers(bursary_providers可以有很多联系人;bursary_administrators可以有很多联系人;联系人属于一个):
Schema::create('bursary_administrators', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('bursary_administrator',64);
$table->timestamps();
});
Schema::create('bursary_provider_contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->integer('bursary_administrator_id')->unsigned()->index();
$table->foreign('bursary_administrator_id')->references('id')->on('bursary_administrators')->onDelete('cascade');
$table->integer('contact_id')->unsigned()->index();
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$table->timestamps();
});
如果您不想遵循 Laravel 命名约定,我强烈建议您不要这样做。主要是因为如果您遵循惯例,它就会起作用,其次,您只是在为自己做更多的工作!
所以您需要做的是将您想要的 table 名称作为关系的第二个参数传递。我不明白你为什么要使用 morphMany,你应该使用 belongsToMany
例子
public function contacts() {
return $this->belongsToMany(App::Contact, 'bursary_provider_contacts');
}
public function bursary_provider () {
return $this->belongsToMany(Bursary provider::class, 'bursary_provider_contacts');
}
编辑
就像关于关系类型的脚注
假设您有一个产品模型、一个订单模型和一个发票模型。
现在产品可以属于订单,也可以属于发票。
这并不能证明多态关系的合理性,这简单意味着您将拥有以下 tables:
产品
命令
发票
order_product
invoice_product
现在是一个多态的例子,Laravel使用这个相同的例子,因为它很常见。
假设您有一个 post 模型、视频模型和评论模型。
现在 posts 模型可以有评论
视频模型可以有评论。
因此,无需构建 PostComment 和 VideoComment 模型,您可以简单地构建 Comment 模型,通过定义多态关系,两个模型的评论将存储为与所需模型相关联。
我不想居高临下,但请认真查看 Laravel 文档,它们非常有用。
https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations
我有以下
Schema::create('bursary_providers', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('bursary_provider',64);
$table->timestamps();
});
Schema::create('bursary_provider_contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->integer('bursary_provider_id')->unsigned()->index();
$table->foreign('bursary_provider_id')->references('id')->on('bursary_providers')->onDelete('cascade');
$table->integer('contact_id')->unsigned()->index();
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$table->timestamps();
});
Schema::create('contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('contact_name', 32);
$table->timestamps();
});
1) 是的,我知道这不符合存储 'type' 的典型惯例。我这样做是为了参照完整性。
2) 我将它存储在一个自定义的名为 pivot table 中,因为它对我来说更有意义。 Laravels pivot table 要求是按字母顺序排列,但让我们保持这样,因为我希望命名为 parent_child
现在,我该如何设置我的模型?根据我的理解,这种情况将是一个 morphMany(除了 'bursary_providers' 之外还有其他 parents - 为了避免混淆而省略)。所以我会在我的 BursaryProvider 模型中使用以下内容:
public function contacts() {
return $this->morphMany('App\Contact');
}
以及我的联系人模型中的以下内容:
public function bursary_provider () {
return $this->morphTo();
}
如何更改以上内容,以便它们使用 bursary_providers.id / contacts.id 和枢轴 table bursary_provider_contacts(bursary_provider_id 和 contact_id )?
// 编辑 为了清楚起见,另一个'parent'而不是bursary_providers(bursary_providers可以有很多联系人;bursary_administrators可以有很多联系人;联系人属于一个):
Schema::create('bursary_administrators', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->string('bursary_administrator',64);
$table->timestamps();
});
Schema::create('bursary_provider_contacts', function (Blueprint $table) {
$table->increments('id')->unsigned()->index();
$table->integer('bursary_administrator_id')->unsigned()->index();
$table->foreign('bursary_administrator_id')->references('id')->on('bursary_administrators')->onDelete('cascade');
$table->integer('contact_id')->unsigned()->index();
$table->foreign('contact_id')->references('id')->on('contacts')->onDelete('cascade');
$table->timestamps();
});
如果您不想遵循 Laravel 命名约定,我强烈建议您不要这样做。主要是因为如果您遵循惯例,它就会起作用,其次,您只是在为自己做更多的工作!
所以您需要做的是将您想要的 table 名称作为关系的第二个参数传递。我不明白你为什么要使用 morphMany,你应该使用 belongsToMany
例子
public function contacts() {
return $this->belongsToMany(App::Contact, 'bursary_provider_contacts');
}
public function bursary_provider () {
return $this->belongsToMany(Bursary provider::class, 'bursary_provider_contacts');
}
编辑
就像关于关系类型的脚注
假设您有一个产品模型、一个订单模型和一个发票模型。
现在产品可以属于订单,也可以属于发票。
这并不能证明多态关系的合理性,这简单意味着您将拥有以下 tables:
产品 命令 发票 order_product invoice_product
现在是一个多态的例子,Laravel使用这个相同的例子,因为它很常见。
假设您有一个 post 模型、视频模型和评论模型。
现在 posts 模型可以有评论
视频模型可以有评论。
因此,无需构建 PostComment 和 VideoComment 模型,您可以简单地构建 Comment 模型,通过定义多态关系,两个模型的评论将存储为与所需模型相关联。
我不想居高临下,但请认真查看 Laravel 文档,它们非常有用。
https://laravel.com/docs/5.6/eloquent-relationships#polymorphic-relations