简体   繁体   中英

How to include related models in Sequelize?

I am trying to retrieve all transactions and include all related stripePayments but get the error include.model.getTableName is not a function .

I have a transactions table that has many stripePayments . This can seen with the following sequelize models:

src/models/transaction.js

module.exports = (sequelize, DataTypes) => {
  class Transaction extends Model {
    static associate(models) {
      this.hasOne(models.StripePayment, { 
        as: 'StripePayment',
        foreignKey: 'stripePaymentId'
      });
    }
  }

  Transaction.init(
    {
      id:{ 
        allowNull: false,
        primaryKey: true,
        type: DataTypes.UUID
      },
      stripePaymentId: {
        type: DataTypes.UUID,
        allowNull: false,
        foreignKey: true,
        references: {
          model: stripePayment,
          key: 'id',
        },
      }
    },
    {
      sequelize,
      modelName: 'Transaction',
    }
  );

  return Transaction;
};

src/models/stripePayment.js

module.exports = (sequelize, DataTypes) => {
  class StripePayment extends Model {
    
    static associate(models) {
      this.belongsTo(models.Transaction, { 
        as: 'Transaction', 
        foreignKey: 'stripePaymentId' 
      });
    }
  }

  StripePayment.init(
    {
      id:{ 
        allowNull: false,
        primaryKey: true,
        type: DataTypes.UUID,
        defaultValue: DataTypes.UUIDV4
      }
    },
    {
      sequelize,
      modelName: 'StripePayment',
    }
  );
  return StripePayment;
};

I then have an index file that imports all the models and calls the association method like so:

src/models/index.js

const db = fs
  .readdirSync(__dirname)
  .filter(isModelFile)
  .reduce((acc, file) => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    acc[model.name] = model;
    return acc;
  }, {});

Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
  console.log(db[modelName], db[modelName].association())
});

The console log outputs the following:

StripePayment, { Transaction: Transaction }
Transaction, { StripePayment: StripePayment}

which I assume means the association has worked?

However, when running a query like:

await models.Transaction.findAll({
  where: { id: "my_id" },
  include: [
    { 
      model: 'StripePayment',
      as: 'stripePayments'
    }
  ]
});

is when I get the error include.model.getTableName is not a function .

What is causing this to fail?

Have I defined the relationships correctly in the models?

Turns out the issue was with my query. I needed to specify the model instance, not the name of the model as a string:

Ie I needed to do this:

await models.Transaction.findAll({
  where: { id: "my_id" },
  include: [
    { 
      model: models.StripePayment,
      as: "StripePayment", // match the alias specified in the  model
      attributes: ['id', 'status'], // need to select attributes
    }
  ]
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM