Sequelize-如何设计一对一关联?

问题描述 投票:0回答:1

我正在创建两个模型,第一个是User,第二个是Portfolio。当用户创建一个Portfolio(一个用户只能有一个Portfolio)时,我希望它引用创建它的用户,并且每次获取该用户的数据时,我都希望它也正在获取他们的投资组合数据。

我正在尝试使用hasOneportfolio_id表中创建User,其骨架是使用sequelize init命令生成的,但是它不起作用。如果不将其放在用户迁移文件中,则找不到名称为protfolio_id的列。那应该是这样吗?

我应该如何设计模型?我应该在portfolio_id表中包含User,还是在user_id表中包含Portfolio,还是有最佳方法?

以及我应该使用哪种关联方法,hasOne或belongsTo?

node.js model sequelize.js associations one-to-one
1个回答
0
投票

首先,请确保您为每种型号都呼叫Model.associate。这将对所有关系运行查询。

您可以按以下方式在关联方法中定义关系:

// user.js (User Model definition)
module.exports = (sequelize, dataTypes) => {
    const { STRING } = dataTypes
    const User = sequelize.define("user", {
        username: { type: STRING }
    })

    User.associate = models => {
        User.hasOne(models.Portfolio, { foreignKey: "userId" }) // If only one portfolio per user
        User.hasMany(models.Portfolio) // if many portfolios per user
    }

    return User
}

// portfolio.js (Portfolio Model definition)
module.exports = (sequelize, dataTypes) => {
    const { STRING } = dataTypes
    const Portfolio = sequelize.define("portfolio", {
        portfolioName: { type: STRING }
    })

    Portfolio.associate = models => {
        Portfolio.belongsTo(models.User, { foreignKey: "userId" })
    }

    return Portfolio
}

hasOne将ForeignKey存储在目标模型中。因此,此关系会将外键userId添加到Portfolio模型。

belongsTo将键存储在当前模型中,并引用目标模型的主键。在这种情况下,Portfolio.belongsTo将在userId模型中添加Portfolio,该模型将引用User模型的主键。

注意这两个关系如何做相同的事情,它们将userId添加到Portfolio模型。最好在最后一个用例的两个模型中都定义这个:

[我希望它引用正在创建它的用户,并且每次获取该用户的数据时,我都希望它也获取其投资组合数据(如果有)。

正在访问相关模型:在序列化中,与主模型一起获取相关模型称为Eager Loading。进一步了解here

现在,如果您要获取投资组合(如果有),请在您的用例中,在获取用户时,执行以下操作:

var userWithPortfolio = await User.findAll({include: [models.Portfolio]};
// Or you may also use include: {all: true} to include all related models.
var userWithPortfolio = await User.findAll({include: {all: true}};

/*  
    Output:

    userWithPortfolio = {
        username: "xyz",
        portfolio: {
            portfolioName: "xyz"
        }
    }
*/
© www.soinside.com 2019 - 2024. All rights reserved.