sequelize.js - 续集验证:对于单个属性,只允许一项为真
问题描述
export default function (sequelize, DataTypes) {
const OrderAddress = sequelize.define('OrderAddress', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
is_default: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: false,
},
receiver_name: {
type: DataTypes.STRING,
allowNull: true,
},
phone_number: {
type: DataTypes.STRING,
allowNull: true,
},
address: {
type: DataTypes.STRING,
allowNull: true,
},
address_detail: {
type: DataTypes.STRING,
allowNull: true,
},
postcode: {
type: DataTypes.STRING,
allowNull: true,
},
}
});
我的orderAddress
模型如上所示,我想进行验证以仅允许将一项is_default
设置为true
.
所以,
const address = {
is_default: true, // default one
}
const address2 = {
is_default: true // no you can't!
}
我应该为此模型制作is_default
字段unique: true
还是添加一些自定义项?validation
解决方案
您可以在order_id
(或任何您的关系字段)和is_defualt
(第一个示例)上添加唯一索引,或者您可以对其进行一些重构以将其设置为default_address
onOrder
而不是将其设置在OrderAddress
(第二个示例)
第一个选项,添加唯一索引
indexes: [
{
fields: ['is_default', 'order_id'], // or whatever your relational field is
unique: true,
},
],
第二个选项,在订单级别检查
假设它OrderAddress
属于Order
模型之类的东西,您还可以在此处添加验证以提高效率。由于您想知道哪个地址是默认地址,并且只允许一个,因此添加一个名为的字段Order.default_address
并将值设置为“地址”或“地址2”的枚举,指示应该使用哪个地址 - 自然只能设置一个而不是两者兼而有之。
Order
然后,您可以在模型上添加一个beforeValidate
钩子,检查设置为“默认”的字段是否包含OrderAddress
.
export default function (sequelize, DataTypes) {
const Order = sequelize.define('Order', {
// your fields
default_address: {
type: DataTypes.ENUM(),
values: ['address', 'address2'],
allowNull: false,
// defaultValue: 'address',
},
{
hooks: {
beforeValidate: function(instance) {
switch (instance.default_address) {
case 'address':
case 'address2': {
// check to see if address_id or address2_id is set, as needed
if (!instance[instance.default_address + '_id') { // or + 'Id' if you use camel case
return Sequelize.Promise.reject(
new Error(`Default "${instance.default_address}" not set`)
);
}
}
default: {
return Sequelize.Promise.reject(
new Error('You must set a default address')
);
}
}
},
}
}
});