【问题标题】:One-To-One Relationship and Making Associations一对一的关系和建立关联
【发布时间】:2014-02-24 21:07:20
【问题描述】:

到目前为止,我真的很喜欢 Sequelize,但有些东西我似乎无法理解并正确设置。我了解数据库架构以及如何编写 SQL,但是当涉及到这种类型的关系时,我对这个 ORM 有一些东西我只是不理解。

我的模型中的两个对象/表需要一对一的关系以及一对多的关系。以下是我将如何描述它...

用户

  • 有很多媒体(应该在媒体表上创建 FK 作为 UserId)
  • 有一个名为 PrimaryMedia 的媒体(应在 User 表上创建 FK 作为 PrimaryMediaId)

我已经阅读了几次文档并尝试了不同的排列以使表格以正确的方式创建,但是我不明白我的对象在 setter/getter 方面有什么期望。即,对于上面的示例,我希望...

用户

  • 有方法 addMedia、removeMedia 和 setMedia
  • 有方法 setPrimaryMedia

设置这两个模型对象的正确方法是什么?

编辑:我已经设法让一对一完全工作,但一对多没有更新外键......

用户.js

...
User.hasMany(models.Media, {
    as: 'Media',
    foreignKeyConstraint: true
}),
User.hasOne(models.Media, {
    as: 'PrimaryMedia'
}),
User.belongsTo(models.Media, {
    as: 'PrimaryMedia',
    foreignKey: 'PrimaryMediaId'
})
...

媒体.js

...
Media.hasOne(models.User, {
    as: 'User',
    foreignKey: 'PrimaryMediaId'
}),
...

在行动中......

Media.create({
    type: 'image',
    nativeURL: nativeURL,
    mediumURL: mediumURL,
    smallURL: smallURL
}).success(function(newMedia) {
    _user.addMedium(newMedia).success(function(){  // THIS ISN'T WORKING (Media.UserId column always null)
        console.log('media user set');
    });
    _user.setPrimaryMedia(newMedia).success(function(){ // THIS IS WORKING
        console.log('user primary media set');
    });
    success(newMedia);
}).error(function(err) {
    error(err);
});

【问题讨论】:

    标签: node.js postgresql sequelize.js


    【解决方案1】:

    也许将属性 'primary' 添加到 Media,并用作:

    user.addMedium(newMedia, { primary: true });
    

    我运行你的代码,它的工作:

    var sequelize = new Sequelize('schema', 'user', 'password', {host: 'localhost'});
    
    User = sequelize.define('User', {name: Sequelize.STRING});
    
    Media  = sequelize.define('Media', {title: Sequelize.STRING});
    
    User.hasMany(Media, {
        as: 'Media',
        foreignKeyConstraint: true
    }),
    
    User.hasOne(Media, {
        as: 'PrimaryMedia'
    }),
    
    User.belongsTo(Media, {
        as: 'PrimaryMedia',
        foreignKey: 'PrimaryMediaId'
    });
    
    sequelize.sync().success(function(){
    
        User.create().success(function(_user){
    
            Media.create({}).success(function(newMedia) {
    
                _user.addMedium(newMedia).success(function(){  // THIS ISN'T WORKING (Media.UserId column always null)
                    console.log('media user set');
                }).error(function(error){
                    console.log('cant add media', error);
                });
    
                _user.setPrimaryMedia(newMedia).success(function(){ // THIS IS WORKING
                    console.log('user primary media set');
                }).error(function(error){
                    console.log('cant set primaryMedia', error);
                });
    
            }).error(function(err) {
                error(err);
            });
    
        }).error(function(error){
            console.log('user create', error)
        })
    
    }).error(function(error){
        console.log('sync error', error);
    });
    

    日志:

    INSERT INTO `Users` (`id`,`createdAt`,`updatedAt`) VALUES (DEFAULT,'2014-02-24 13:01:57','2014-02-24 13:01:57');
    INSERT INTO `Media` (`id`,`createdAt`,`updatedAt`) VALUES (DEFAULT,'2014-02-24 13:01:57','2014-02-24 13:01:57');
    SELECT * FROM `Media` WHERE `UserId` = 1 AND `Media`.`id` = 1;
    UPDATE `Users` SET `PrimaryMediaId`=1,`updatedAt`='2014-02-24 13:01:57' WHERE `id`=1
    user primary media set
    UPDATE `Media` SET `id`=1,`createdAt`='2014-02-24 13:01:57',`updatedAt`='2014-02-24 13:01:57',`UserId`=1 WHERE `id`=1
    media user set
    

    【讨论】:

    • 我在开发人员的帮助下发现了问题。这部分是缺少 belongsTo() 的问题,但主要是因为稍后再次导入模型会影响关系。我将模型附加到续集并且它起作用了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-22
    • 2011-06-19
    • 1970-01-01
    • 1970-01-01
    • 2023-04-11
    相关资源
    最近更新 更多