【问题标题】:On sequelize, "include" of "findOne" not working在续集上,“findOne”的“包含”不起作用
【发布时间】:2015-04-22 02:34:44
【问题描述】:

我做了一个简单的测试,即搜索一个地址(id = 4)并检索链接到该地址的用户。

这是我的模型:

user.js

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('User', {
        id: {
            type: DataTypes.INTEGER(10).UNSIGNED,
            allowNull: false,
            field: 'id',
            //primaryKey: true,
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false,
            field: 'name',
        },
    }, {
        freezeTableName: true,
        tableName: 'user',
        createdAt: false,
        updatedAt: false,
        classMethods: {
            associate: function(models) {
                models.User.hasMany(models.UserAddress, { foreignKey: 'userId' });
            },
        },
    });
};

user_address.js

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('UserAddress', {
        id: {
            type: DataTypes.INTEGER(10).UNSIGNED,
            allowNull: false,
            field: 'id',
        },
        userId: {
            type: DataTypes.INTEGER(10).UNSIGNED,
            allowNull: false,
            field: 'user_id',
        },
        title: {
            type: DataTypes.STRING,
            allowNull: true,
            field: 'title',
        },
        address: {
            type: DataTypes.STRING,
            allowNull: true,
            field: 'address',
        },
    }, {
        freezeTableName: true,
        tableName: 'user_address',
        createdAt: false,
        updatedAt: false,
        classMethods: {
            associate: function(models) {
                models.UserAddress.hasOne(models.User, { foreignKey: 'id' });
            },
        },
    });
};

这是我的测试文件:

db.UserAddress.findOne({
    where: { id: 4 },
    include: [db.User],
}).then(function(address) {
    console.log('------------------------------ Address by "include"');
    console.log('Address title: '+address.title);
    console.log('User id: '+address.userId);
    if(address.User !== null) {
        console.log('User name: '+address.User.name);
    } else {
        console.log('User name: NO USER');
    }

    console.log('');
    address.getUser().then(function(user) {
        console.log('------------------------------ Address by "getUser"');
        console.log('Address title: '+address.title);
        console.log('User id: '+address.userId);
        if(user !== null) {
            console.log('User name: '+address.user.name);
        } else {
            console.log('User name: NO USER');
        }
        console.log('');
    });
});

我用两个测试进行查询:

  • 第一个旨在通过变量“user”直接恢复用户,因此感谢请求的“包含”。
  • 另一个也检索用户,但这次是通过“getUser()”。

结果如下:

$ node test.js
Executing (default): SELECT `UserAddress`.`id`, `UserAddress`.`user_id` AS `userId`, `UserAddress`.`title`, `UserAddress`.`address`, `User`.`id` AS `User.id`, `User`.`name` AS `User.name` FROM `user_address` AS `UserAddress` LEFT OUTER JOIN `user` AS `User` ON `UserAddress`.`id` = `User`.`id` WHERE `UserAddress`.`id`=4;
------------------------------ Address by "include"
Address title: Test
User id: 3
User name: NO USER

Executing (default): SELECT `id`, `name` FROM `user` AS `User` WHERE (`User`.`id`=4);
------------------------------ Address by "getUser"
Address title: Test
User id: 3
User name: NO USER

可以观察到无法通过“include”和“getUser()”检索结果。 错误在 SQL 的日志中可见:

"include": LEFT OUTER JOIN `user` AS `User` ON `UserAddress`.`id` = `User`.`id`
and
"getUser()": SELECT `id`, `name` FROM `user` AS `User` WHERE (`User`.`id`=4);

虽然正确答案应该是:

"include": LEFT OUTER JOIN `user` AS `User` ON `UserAddress`.`user_id` = `User`.`id`
and
"getUser()": SELECT `id`, `name` FROM `user` AS `User` WHERE (`User`.`id`=3);

所以我的问题是,要放入我的模型中的配置是什么,或者我对“include”和“getUser()”的结果是否正确的要求是什么?

谢谢。

(也发布在:https://github.com/sequelize/sequelize/issues/3182

【问题讨论】:

  • 有些地方不太对劲:您将 SQL 显示为只有 id,但在 user.js 中您有 userId。 Sequelize 在没有默认大写(驼峰式)时会奇怪地处理外键。您可以做的是更改user.jsuser_address.js 中关联的foreignKey 字段,直到获得正确的查询。那应该只是几次尝试。我过去的一种方法是models.User.hasMany(models.UserAddress, { foreignKey: 'user_id' });models.UserAddress.belongsTo(models.User, { foreignKey: 'user_id' });
  • 解决方案是在 Github 上给我:github.com/sequelize/sequelize/issues/…
  • 哦,好吧...至少我认为我是对的,除了user_id 的大写。 :) 您可以在此处复制解决方案并将答案标记为已接受,以便其他人也可以看到解决方案。

标签: javascript node.js sequelize.js


【解决方案1】:

来自github page 的答案 - 需要使用belongsTo 而不是hasOne

user.js

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('User', {
        id: {
            type: DataTypes.INTEGER(10).UNSIGNED,
            allowNull: false,
            field: 'id',
            //primaryKey: true,
        },
        name: {
            type: DataTypes.STRING,
            allowNull: false,
            field: 'name',
        },
    }, {
        freezeTableName: true,
        tableName: 'user',
        createdAt: false,
        updatedAt: false,
        classMethods: {
            associate: function(models) {
                models.User.hasMany(models.UserAddress, { foreignKey: 'userId' });
            },
        },
    });
};

user_address.js

module.exports = function(sequelize, DataTypes) {
    return sequelize.define('UserAddress', {
        id: {
            type: DataTypes.INTEGER(10).UNSIGNED,
            allowNull: false,
            field: 'id',
        },
        userId: {
            type: DataTypes.INTEGER(10).UNSIGNED,
            allowNull: false,
            field: 'user_id',
        },
        title: {
            type: DataTypes.STRING,
            allowNull: true,
            field: 'title',
        },
        address: {
            type: DataTypes.STRING,
            allowNull: true,
            field: 'address',
        },
    }, {
        freezeTableName: true,
        tableName: 'user_address',
        createdAt: false,
        updatedAt: false,
        classMethods: {
            associate: function(models) {
                models.UserAddress.belongsTo(models.User, { foreignKey: 'userId' });
            },
        },
    });
};

【讨论】:

    猜你喜欢
    • 2020-02-08
    • 2019-11-16
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 2015-07-23
    • 2016-02-17
    • 2014-07-01
    相关资源
    最近更新 更多