Sequelize Many to Many Query Issue

你。 提交于 2020-01-06 06:02:42

问题


So, I have an existing MySQL database that I'm trying to connect to with Sequelize in Node that has a products table, a categories table and a categories_products table. What I want to do is return products, with each product containing all of the categories it belongs to. Here's what I've got:

// Declare Product Model
const Product = sequelize.define('products', {
    name: Sequelize.STRING,
    description: Sequelize.STRING,
    single_price: Sequelize.BOOLEAN,
    oz_price: Sequelize.FLOAT,
    half_price: Sequelize.FLOAT,
    quarter_price: Sequelize.FLOAT,
    eigth_price: Sequelize.FLOAT,
    gram_price: Sequelize.FLOAT,
    unit_price: Sequelize.FLOAT
},
{
    underscored: true
});

// Declare Category Model
const Category = sequelize.define('categories', {
    name: Sequelize.STRING,
    parent_id: Sequelize.INTEGER,
    picture_file_name: Sequelize.STRING
},
{
    underscored: true
});

// Join Table
const ProductCategory = sequelize.define('categories_products', {
    product_id: Sequelize.INTEGER,
    category_id: Sequelize.INTEGER,

}, {  
    timestamps: false,
    underscored: true
});

// Do this because there is no id column on ProductCategory table
ProductCategory.removeAttribute('id');

Category.hasMany(Category, { as: 'children', foreignKey: 'parent_id' });

ProductCategory.belongsTo(Product);
ProductCategory.belongsTo(Category);
Product.hasMany(ProductCategory);
Category.hasMany(ProductCategory);

Using this setup, I query as follows:

Product.findAll({
    include: [{
        model: ProductCategory,
        include: [ Category ]
    }],
    where: { active: true },
    limit: 10
}).then(prods => {
    res.send(prods);
}).catch(err => {
    res.status(500).send(err);
});

I get back my products and each one has an array of categories, BUT each product only shows a max of one category. I have products that should have many categories, but it only shows the first.

Am I missing something? Any help would be greatly appreciated.


回答1:


I think you should use belongsToMany association here.

You can define association like this

Product.belongsToMany(Category, { through: ProductCategory, foreignKey: 'product_id' });
Category.belongsToMany(Product, { through: ProductCategory, foreignKey: 'category_id' });

and the query can be

Product.findAll({
  include: [Category]
}).then((res) => {
  console.log(res);
})



回答2:


Though the questioner might have gotten the solution but I ran into this composite key table problem and this is the solution with code example. Notice the "through" keyword. That is what solves the association where you want to limit your findings to say a category as AbhinavD asked above. Your category id would go in the literal expression. Applies to findAll too.

const products = await Product.findAndCountAll({
        include: [Category],
        through: { where: { category_id: `${category_id}` } },
        attributes: [
          'product_id',
          'name',

        ],

        limit: limitPage,
        offset: offsett,
      });


来源:https://stackoverflow.com/questions/50755339/sequelize-many-to-many-query-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!