与 bookshelf.js 的多个多对多关系

Posted

技术标签:

【中文标题】与 bookshelf.js 的多个多对多关系【英文标题】:multiple many to many relationships with bookshelf.js 【发布时间】:2016-02-23 06:50:19 【问题描述】:

我正在尝试确定使用 Bookshelf.js 表示以下内容的最佳方式:

我有一个Appointment 模型,每个Appointment 都有:

1 个或多个Pet(s) 1 个或多个 Service(s)

我可以使用 Bookshelf 中的多对多关系轻松表示这一点,这会产生三个表:appointmentappointment_petappointment_service

我现在有一个新要求,要求能够在每次预约的基础上指定与每个Pet 关联的Service(s),以便可以轻松检索与特定宠物关联的服务。例如:

约会 1

有 1 只宠物 有 2 个服务(walkwater plants) 宠物仅与walk 服务相关联。

获取与Appointment 1 关联的Pet 的所有服务将返回walk

是否有使用 Bookshelf 表示此场景的最佳方式?

【问题讨论】:

【参考方案1】:

我正在考虑任何Pet 始终与Service 相关联。在这种情况下,我会像这样构建它:

正如Service 模型作为AppointmentPets 之间的桥梁。 Service 可以有宠物(例如,当它是 walk 时)或没有宠物(例如,当它是 water plants 时)。 BookshelfJS 模型如下所示:

var Appointment = bookshelf.Model.extend(
  services: function () 
    return this.hasMany('Service');
  ,
  pets: function () 
    return this.hasMany('Pet').through('Service');
  ,
);

一个可能的问题是您最终会得到许多相同类型的不同Services,但AppointmentPet 的组合不同。如果Service 上的属性不多,这没有问题。例如,如果Service 只有一个type 属性。

如果您想为Service 添加更多属性,例如pricetime_duration 等,您可以将其提取到自己的表中,如下所示:

然后Service 表将包含每种类型的服务及其属性(例如pricetime_duration、...)。代码如下所示:

var Appointment = bookshelf.Model.extend(
  services: function () 
    return this.hasMany('Service').through('AppointmentService');
  ,
  pets: function () 
    return this.hasMany('Pet').through('AppointmentService');
  ,
);

我建议使用更简单的情况,然后根据需要进行更改。您可能还需要使用withPivot 方法从关系表中获取值。

【讨论】:

嗨 Vitor - 感谢您的解决方案。这主要是可行的——我必须将hasMany 更改为belongsToMany,它可以正常工作。我唯一的问题是withPivot 似乎没有任何效果。无论我是否添加withPivot,都会返回数据透视数据,但它缺少数据。例如,查看pets 的数据透视表时,它返回idappointment_idpet_id,但没有service_id,这是我真正需要的。我尝试做this.belongsToMany('Pet').through('AppointmentService').withPivot(['service_id'];,但没有任何效果。想法?谢谢! 似乎withPivot 不适用于through 关系。不确定这是否是一个错误。 你在使用可见性插件吗?请记住,数据透视表前面带有_pivot,因此数据透视表中的service_id 将变为_pivot_service_id 如果有人偶然发现这一点,withPivot 不适用于 through。你必须做类似this.belongsToMany(OtherModel, "pivot_table").withPivot(["col1"]);

以上是关于与 bookshelf.js 的多个多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

通过 SQLAlchemy 选择多个多对多关系

具有额外多对多关系的 JPA 多对多

Bookshelf.js - 如何从连接表中获取列?

Hibernate多表关系配置——多对多对关系映射

Laravel Datatable 与多个表的多对多关系

与多个中间表的多对多 Laravel Eloquent 关系