Nested include in sequelize?
Asked Answered
S

5

44

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 ?

Salted answered 26/11, 2015 at 15:14 Comment(0)
C
58
models.products.findAll({
  include: [
    {model: models.comments, include: [models.comments.users] }
  ]
}) 
Culmiferous answered 26/11, 2015 at 17:55 Comment(3)
please add some explanation to your answerMidterm
This solution does not work as written (at least not in the version I have, 3.24.1). The inner include should be 'include: [models.users]'.Oleomargarine
Be carefull if this is a many-to-many association. In this case you should use hasMany when define association.Levo
C
15

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
    }]
  }]
});
Coryden answered 9/1, 2021 at 19:8 Comment(1)
This seems to compile, but I have an error on my side : column X->Y.link dos not exist. But I have in X : HasMany Y and in Y I have BelongsTo X. I don't understand why I can't include this way in typescript sequelizeTable
O
6

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 }});
Outleap answered 21/4, 2022 at 11:42 Comment(0)
D
4

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
});
Diggs answered 12/5, 2022 at 21:0 Comment(0)
A
-5

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.

Acid answered 28/7, 2017 at 12:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.