简体   繁体   中英

Sequelize.js findAll with include to search foreign_key makes page never load

Description

I have a simple database that consists of a Customer, Address, and Order. I'm trying to find all orders where the address is some string. For example I can provide the city or state and I want to lookup based on that.

Orders Table: 在此处输入图片说明

Address Table: 在此处输入图片说明

Orders Model:

module.exports = db.define('orders', {
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    repId: { type: Sequelize.INTEGER },
    totalItemCost: { type: Sequelize.DECIMAL(10,2), allowNull: false},
    shippingCost: { type: Sequelize.DECIMAL(10,2), allowNull: false},
    orderDate: { type: Sequelize.DATE, allowNull: false},
    isPaid: { type: Sequelize.BOOLEAN, allowNull: false},
    taxPercentage: { type: Sequelize.DECIMAL(10,4), allowNull: false},
}, {timestamps: false, freezeTableName: true, tableName: 'Orders'});

Address Model:

module.exports = db.define('address', {
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    firstName: { type: Sequelize.STRING, allowNull: false},
    lastName: { type: Sequelize.STRING, allowNull: false},
    city: { type: Sequelize.STRING, allowNull: false},
    address: { type: Sequelize.STRING(256), allowNull: false},
    zip: { type: Sequelize.STRING(10), allowNull: false},
}, {timestamps: false, freezeTableName: true, tableName: 'Address'});

Relations:

var models = {};
models.Address = require("./models/address.js");
models.Customer = require("./models/customer.js");
models.Orders = require("./models/orders.js");

// Orders Relations
models.Orders.belongsTo(models.Customer, { foreignKey: { name: 'customerId', allowNull: false }});
models.Orders.belongsTo(models.Address, { foreignKey: { name: 'shippingAddressId', allowNull: false }});

The Problem

Say for example I want to find all orders where the city is Birchwood. I'm using include in my findAll command with the model set to my address and because I've specifically named my shipping address, setting the "as" statement. This results in the page never loading and I'm not sure what I'm doing wrong. If I remove the include command, all my orders load fine. I don't see any examples for include when "belongsTo" was used. When "hasMany" is used it looks like "association" is used instead of "foreign_key". Is that the problem why "as" isn't working?

models.Orders.findAll({
    where: where,
    include: [{
        model: models.Address, 
        as: 'shippingAddressId',
    }] 
}).then(function(orders) { 
    res.json(orders);
}).catch(function(err) {
    res.status(500).json({"error": err});
});

EDIT 1

I added in error handling for my query statement, but this now just outputs {"error":{}}. There error is blank so that's not very helpful. If I remove the "as: 'shippingAddressId'" line, then the model loads, and just puts the address under the field "address" in the json structure which is not desired. Adding a where clause to that causes it to return an empty object {}. I basically want include: [{ all: true, nested: true }] but also filtered on the relationship Address.

Obviously there is an error in the query. Thats why res.json(orders); never called. I don't see error handling in you code. Take a look at http://bluebirdjs.com/docs/api/catch.html . When you will catch error, output it and see exactly whats going on.

I solved this issue by adding the association to my relationships:

// Orders Relations
models.Orders.belongsTo(models.Customer, { as: 'customer', onDelete: 'CASCADE', foreignKey: { name: 'customerId', allowNull: false }});
models.Orders.belongsTo(models.Address, { as: 'shippingAddress', onDelete: 'CASCADE', foreignKey: { name: 'shippingAddressId', allowNull: false }});
models.Orders.belongsTo(models.PaymentMethod, { as: 'paymentMethod', onDelete: 'CASCADE', foreignKey: { name: 'paymentMethodId', allowNull: false }});
models.OrderItem.belongsTo(models.Orders, { as: 'order', onDelete: 'CASCADE', foreignKey: { name: 'orderId', allowNull: false }});

And then using that association name in my query:

models.Orders.findAll({
    where: where,
    include: [{
        model: models.Address,
        as: 'shippingAddress',
        where: {
            city: {like: "%Wedgewood%" }
        }
    }]
}).then(function(orders) { 
    res.json(orders);
}).catch(function(err) {
    res.status(500).json({"error": err});
});

I was under the impression that that association was automatically made.

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