序列验证:单个属性仅允许一项为真

时间:2019-04-01 07:01:07

标签: 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

2 个答案:

答案 0 :(得分:0)

可能有几种方法可以实现这一目标。

  1. Sequelize为hooks提供了一个选项,该选项在查询生命周期中的特定事件上触发。
    使用beforeCreateafterValidate钩子,您可以进行访存并查找是否有is_defaulttrue的记录,只是抛出一个错误。
  2. 在数据库层上添加一个trigger,以检查是否存在任何带有is_default的行。可以通过顺序迁移来添加和管理此类触发器

答案 1 :(得分:0)

您可以在order_id(或任何关系字段)和is_defualt(第一个示例)上添加唯一索引,也可以对其进行重构以设置{{1} },而不是在default_address上进行设置(第二个示例)

第一个选项,添加唯一索引

Order

第二个选项,在订单级别检查

假设OrderAddress属于indexes: [ { fields: ['is_default', 'order_id'], // or whatever your relational field is unique: true, }, ], 模型,您也可以在此处添加验证以提高效率。由于您想知道哪个地址是默认地址,并且只允许一个地址,因此添加一个名为OrderAddress的字段,并将值设置为“ address”或“ address2”的枚举,以指示应使用哪个地址-自然只能设置一个,不能同时设置两个。

然后在Order模型上,您可以添加一个Order.default_address钩子,以检查设置为“默认”的字段是否包含Order的ID。

beforeValidate