Sequelize.js - 如何在没有原始 SQL 的情况下创建非平凡的关联?
Sequelize.js - How to create non-trivial associations without raw SQL?
这是我的情况:
我正在使用 postgres 9.4,Sequelize ORM 并具有以下模型:
服务
- serviceCode - 主键,6 个字符的字符串
- serviceTitle - 字符串
服务组
- serviceCodePrefixes - 作为 Service.serviceCode
前缀的字符串数组
- serviceGroupTitle - 字符串
任务
- serviceCode - 对服务的引用
我需要构建填充有 Service 和 ServiceGroup 对象的 Task 对象。 示例:
In database:
Service {
serviceCode: '123232',
serviceTitle: 'svc title #1',
}
ServiceGroup {
serviceCodePrefix: ['12', '13', '92', ...],
serviceGroupTitle: 'svc grp title #1',
}
Task {
serviceCode: '123232',
}
Result:
Task {
service: {
serviceTitle: 'svc title #1',
},
serviceGroup: {
serviceGroupTitle: 'svc grp title #1',
},
}
问题在于 serviceCodePrefix 包含的不是简单的 ID,它可用于使用 hasOne/belongsTo/etc 创建关联,而是 ID 的前缀。
所以问题是:没有原始 sql 如何做到这一点?
事实证明,现在 Sequelize 具有实验性功能:'on' 'include' 选项。此选项允许用户自定义加入条件。所以我的问题可以这样解决:
const Service = sequelize.define('service', {
serviceTitle: Sequelize.STRING,
serviceCode: Sequelize.STRING,
});
const ServiceGroup = sequelize.define('service_group', {
serviceGroupTitle: Sequelize.STRING,
// Array of prefixes (e.g. ['01%', '023%'])
serviceCodePrefix: Sequelize.ARRAY(Sequelize.STRING),
});
const Task = sequelize.define('task', {
taskTitle: Sequelize.STRING,
serviceCode: Sequelize.STRING,
});
Task.belongsTo(Service, { foreignKey: 'serviceCode' });
// Hack needed to allow 'include' option to work
Task.hasMany(ServiceGroup, { foreignKey: 'serviceCodePrefix', constraints: false });
// And finally
Task.findAll({
include: [
{ model: Service },
{
model: ServiceGroup,
on: [' "task"."serviceCode" LIKE ANY("serviceGroup"."serviceCodePrefix") '],
},
],
});
虽然不确定性能。
这是我的情况:
我正在使用 postgres 9.4,Sequelize ORM 并具有以下模型:
服务
- serviceCode - 主键,6 个字符的字符串
- serviceTitle - 字符串
服务组
- serviceCodePrefixes - 作为 Service.serviceCode 前缀的字符串数组
- serviceGroupTitle - 字符串
任务
- serviceCode - 对服务的引用
我需要构建填充有 Service 和 ServiceGroup 对象的 Task 对象。 示例:
In database:
Service {
serviceCode: '123232',
serviceTitle: 'svc title #1',
}
ServiceGroup {
serviceCodePrefix: ['12', '13', '92', ...],
serviceGroupTitle: 'svc grp title #1',
}
Task {
serviceCode: '123232',
}
Result:
Task {
service: {
serviceTitle: 'svc title #1',
},
serviceGroup: {
serviceGroupTitle: 'svc grp title #1',
},
}
问题在于 serviceCodePrefix 包含的不是简单的 ID,它可用于使用 hasOne/belongsTo/etc 创建关联,而是 ID 的前缀。
所以问题是:没有原始 sql 如何做到这一点?
事实证明,现在 Sequelize 具有实验性功能:'on' 'include' 选项。此选项允许用户自定义加入条件。所以我的问题可以这样解决:
const Service = sequelize.define('service', {
serviceTitle: Sequelize.STRING,
serviceCode: Sequelize.STRING,
});
const ServiceGroup = sequelize.define('service_group', {
serviceGroupTitle: Sequelize.STRING,
// Array of prefixes (e.g. ['01%', '023%'])
serviceCodePrefix: Sequelize.ARRAY(Sequelize.STRING),
});
const Task = sequelize.define('task', {
taskTitle: Sequelize.STRING,
serviceCode: Sequelize.STRING,
});
Task.belongsTo(Service, { foreignKey: 'serviceCode' });
// Hack needed to allow 'include' option to work
Task.hasMany(ServiceGroup, { foreignKey: 'serviceCodePrefix', constraints: false });
// And finally
Task.findAll({
include: [
{ model: Service },
{
model: ServiceGroup,
on: [' "task"."serviceCode" LIKE ANY("serviceGroup"."serviceCodePrefix") '],
},
],
});
虽然不确定性能。