ihoryam
ihoryam

Reputation: 2521

Nested include in sequelize?

How to perform nested include ? I have table products that has one to many relation with comments, and table comments has many to one relation with users table. So comments has user_id, and product_id. My code is like this

var models = require('../models');

models.products.findAll({
    include: [
        {model: models.comments}
    ]
  }).then(function (products) {
    next(products);
  }).catch(function (err) {
    next(err);
  });
});

I get the comments, but I would like to have something like

models.products.findAll({
    include: [
        {model: models.comments.include(models.comments.users)}
    ]
  }) 

Is this possible without writing custom queries ?

Upvotes: 46

Views: 61748

Answers (5)

Brass
Brass

Reputation: 51

In case this helps someone in the future:

I was nesting multiple levels deep, and I kept getting Typescript errors that my call didn't match any overrides.

For me, it was not clear in the previous answers (or the docs) that you must wrap the include object in an array at all levels (even in you only provide 1 object).

Works:

User.findAll({
  include: [{
    model: Contact,
    include: [{
      model: Address,
      include: [{
        model: City,
        include: [State, Country]
      }]
    }]
  }]
});

Does NOT Work:

User.findAll({
  include: { // <-- notice the missing square bracket
    model: Contact,
    include: { // <-- notice the missing square bracket
      model: Address,
      include: { // <-- notice the missing square bracket
        model: City,
        include: [State, Country]
      } // <-- notice the missing square bracket
    } // <-- notice the missing square bracket
  } // <-- notice the missing square bracket
});

Upvotes: 5

There is a very simple and concise way! https://sequelize.org/docs/v6/advanced-association-concepts/eager-loading/#including-everything

// Fetch all models associated with User
User.findAll({ include: { all: true }});

// Fetch all models associated with User and their nested associations (recursively) 
User.findAll({ include: { all: true, nested: true }});

Upvotes: 6

Quentin C
Quentin C

Reputation: 1893

Solution provided didn't work for me, this is the typescript version I use and guessing the sequelize versions:

// sequelize-typescript
models.products.findAll({
  where,
  include: [{
    model: Comment,
    include: [User]
  }]
});

// without typescript (guessing here)
models.products.findAll({
  where,
  include: [{
    model: models.comments,
    include: [{
      model: models.users
    }]
  }]
});

Upvotes: 16

johnkork
johnkork

Reputation: 664

You can use include.

For example :

Category = sequelize.define(...);
Product = sequelize.define(...);
Product.belongsTo(Category, {foreignKey: 'fk_category'});

Product.findAll({
    include: [{
        model: Category
    }]
});

Will retrieve the nested Category, and not just the id, in a category property.

Upvotes: -5

Jan Aagaard Meier
Jan Aagaard Meier

Reputation: 28798

models.products.findAll({
  include: [
    {model: models.comments, include: [models.comments.users] }
  ]
}) 

Upvotes: 63

Related Questions