与 bookshelf.js 的多个多对多关系
Posted
技术标签:
【中文标题】与 bookshelf.js 的多个多对多关系【英文标题】:multiple many to many relationships with bookshelf.js 【发布时间】:2016-02-23 06:50:19 【问题描述】:我正在尝试确定使用 Bookshelf.js 表示以下内容的最佳方式:
我有一个Appointment
模型,每个Appointment
都有:
Pet
(s)
1 个或多个 Service
(s)
我可以使用 Bookshelf 中的多对多关系轻松表示这一点,这会产生三个表:appointment
、appointment_pet
和 appointment_service
。
我现在有一个新要求,要求能够在每次预约的基础上指定与每个Pet
关联的Service
(s),以便可以轻松检索与特定宠物关联的服务。例如:
约会 1
有 1 只宠物 有 2 个服务(walk
、water plants
)
宠物仅与walk
服务相关联。
获取与Appointment 1
关联的Pet
的所有服务将返回walk
。
是否有使用 Bookshelf 表示此场景的最佳方式?
【问题讨论】:
【参考方案1】:我正在考虑任何Pet
始终与Service
相关联。在这种情况下,我会像这样构建它:
正如Service
模型作为Appointment
和Pet
s 之间的桥梁。 Service
可以有宠物(例如,当它是 walk
时)或没有宠物(例如,当它是 water plants
时)。 BookshelfJS 模型如下所示:
var Appointment = bookshelf.Model.extend(
services: function ()
return this.hasMany('Service');
,
pets: function ()
return this.hasMany('Pet').through('Service');
,
);
一个可能的问题是您最终会得到许多相同类型的不同Service
s,但Appointment
和Pet
的组合不同。如果Service
上的属性不多,这没有问题。例如,如果Service
只有一个type
属性。
如果您想为Service
添加更多属性,例如price
、time_duration
等,您可以将其提取到自己的表中,如下所示:
然后Service
表将包含每种类型的服务及其属性(例如price
、time_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
的数据透视表时,它返回id
、appointment_id
和pet_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 的多个多对多关系的主要内容,如果未能解决你的问题,请参考以下文章