Sequelize 在查询中包含多个表

Sequelize include multiple tables in query

所以我有以下结构收据 -> 政策 -> policholders

每张收据属于一份保单,每份保单属于保单持有人

我想做的是,当我获取收据时,我得到一个包含保单和保单持有人的对象(我正在使用 feathers-sequelize,钩子包含在下面)。我收到保单持有人与收据无关的错误

期望的回复:

{
    "ReceiptId": 1,
    "Supplement": 10.1,
    "policy": {
        "PolicyNumber": 1234
    },
    "policyholder": {
        "Name": "Joe",
        "Surname": "Blogs"
    }
}

政策模式

// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require("sequelize");
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get("sequelizeClient");

  const policies = sequelizeClient.define(
    "policies",
    {
      PolicyId: {
        autoIncrement: true,
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
      },
      PolicyNumber: {
        type: DataTypes.STRING(30),
        allowNull: true,
      },
      CompanyId: {
        type: DataTypes.INTEGER,
        allowNull: true,
      },
      PolicyholderId: {
        type: DataTypes.INTEGER,
        allowNull: true,
      },
    },
    {
      hooks: {
        beforeCount(options) {
          options.raw = true;
        },
      },
    }
  );

  // eslint-disable-next-line no-unused-vars
  policies.associate = function (models) {
    // Define associations here
    // See http://docs.sequelizejs.com/en/latest/docs/associations/
    const { policyholders, companies } = models;
    policies.belongsTo(policyholders, { foreignKey: "PolicyholderId" });

  };

  return policies;
};

投保人模型

// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require("sequelize");
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get("sequelizeClient");
  const policyholders = sequelizeClient.define(
    "policyholders",
    {
      PolicyholderId: {
        autoIncrement: true,
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
      },
      Name: {
        type: DataTypes.STRING(250),
        allowNull: true,
      },
      Surname: {
        type: DataTypes.STRING(250),
        allowNull: true,
      },
    },
    {
      hooks: {
        beforeCount(options) {
          options.raw = true;
        },
      },
    }
  );

  // eslint-disable-next-line no-unused-vars
  policyholders.associate = function (models) {
    // Define associations here
    // See http://docs.sequelizejs.com/en/latest/docs/associations/
    const { policies } = models;

    policyholders.hasMany(policies, { foreignKey: "PolicyholderId" });
  };

  return policyholders;
};

收据模型

// See http://docs.sequelizejs.com/en/latest/docs/models-definition/
// for more of what you can do here.
const Sequelize = require("sequelize");
const DataTypes = Sequelize.DataTypes;

module.exports = function (app) {
  const sequelizeClient = app.get("sequelizeClient");
  const receipts = sequelizeClient.define(
    "receipts",
    {
      ReceiptId: {
        autoIncrement: true,
        type: DataTypes.INTEGER,
        allowNull: false,
        primaryKey: true,
      },
      PolicyId: {
        type: DataTypes.INTEGER,
        allowNull: true,
      },
      Supplement: {
        type: DataTypes.INTEGER,
        allowNull: true,
      },
    },
    {
      hooks: {
        beforeCount(options) {
          options.raw = true;
        },
      },
    }
  );

  // eslint-disable-next-line no-unused-vars
  receipts.associate = function (models) {
    // Define associations here
    // See http://docs.sequelizejs.com/en/latest/docs/associations/
    const { policies } = models;
    receipts.belongsTo(policies, { foreignKey: "PolicyId" });

  };

  return receipts;
};

获取相关钩子

module.exports = function (options = {}) {
  return async (context) => {
    const { include, ...query } = context.params.query;

    const Policies = context.app.services.policies.Model;
    const Policyholders = context.app.services.policyholders.Model;

    context.params.sequelize = {
      include: [Policies, Policyholders],
      raw: false,
    };

    // Update the query to not include `include`
    context.params.query = query;

    return context;
  };
};

如果 Placeholders 通过 Policies 链接到 Receipts 那么您需要在 Policies 本身的 include 选项中指明 Placeholders :

 context.params.sequelize = {
      include: [{
        model: Policies,
        include: [Policyholders]
      }],
      raw: false,
    };