Sequelize hasMany、belongsTo 或两者兼而有之?

Zen*_*nDD 10 sql postgresql node.js sequelize.js

我想使用 sequelize 正确设置一对一或一对多的关系,事实上,如果我在我的模型定义中使用hasOne/hasMany或其中之一,一切似乎都可以正常工作belongsTo。例如,以下关联会userId在其目标上创建字段:

    User.hasMany(Email, {
        as: 'emails',
        foreignKey: 'userId',
    })

    User.hasOne(Profile, {
        as: 'profile',
        foreignKey: 'userId',
    })
Run Code Online (Sandbox Code Playgroud)

但几乎在官方文档的任何地方,我都会看到类似的内容:

   Projects.hasMany(Tasks);
   Tasks.belongsTo(Projects);
Run Code Online (Sandbox Code Playgroud)

hasManyANDbelongsTo被一起使用。

这真的是必需的还是仅使用其中之一就足够了?任何进一步的解释将是非常有价值的。谢谢!

chr*_*opp 11

UsingbelongsTo定义了关联模型的所有权。为了更详细地解释这一点,我将参考教程中引用的示例

Project.hasMany(Task);
Task.belongsTo(Project);
Run Code Online (Sandbox Code Playgroud)

假设您不再对已删除项目的任务感兴趣。在这种情况下,如果您没有定义belongsTo关联,您将不得不手动删除任务。belongsTo建立项目对其任务的所有权,数据库也会自动删除属于已删除项目的任务。这被称为cascading delete并且可以链接多个表。

如果您运行以下代码片段

const Project = sequelize.define('project', {
    name: Sequelize.STRING
});
const Task =  sequelize.define('task', {
    name: Sequelize.STRING
});
Project.hasMany(Task);
Task.belongsTo(Project);
Run Code Online (Sandbox Code Playgroud)

在续集脚本中并观察输出

Executing (default): DROP TABLE IF EXISTS `projects`;
Executing (default): CREATE TABLE IF NOT EXISTS `projects` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`projects`)
Executing (default): DROP TABLE IF EXISTS `tasks`;
Executing (default): CREATE TABLE IF NOT EXISTS `tasks` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `projectId` INTEGER REFERENCES `projects` (`id`) ON DELETE SET NULL ON UPDATE CASCADE);
Run Code Online (Sandbox Code Playgroud)

您会注意到在创建任务表时设置的级联行为。

说了这么多,最后的答案是:看情况。belongsTo如果您宁愿保留已删除项目的任务,则使用可能会非常方便,或者将是致命的。仅belongsTo在您的应用程序上下文中有意义时才使用。