简体   繁体   中英

Unable to establish one-to-one relation with Sequelize

I declared:

Item.hasOne(Item, { foreignKey: 'parentAid', as: 'Parent' })

I queried:

Item.find({where : {aid: aid}, include: [Item]}).complete(function(err, article) { .. };

And I get:

Error: Item is not associated to Item!

What am I doing wrong?

..............................................................................................

UPDATE 1

Thanks to the helpful answer by Jan Aargaard Meier , I was able to change things to:

ItemModel.belongsTo(ItemModel, { foreignKey: 'parentAid', as: 'Parent', foreignKeyConstraint: true });
ItemModel.hasMany(ItemModel, { as: 'Children', constraints: false });

this.articleRelations.push({
    model: ItemModel,
    as: 'Parent'
});

this.articleRelations.push({
    model: ItemModel,
    as: 'Children'
});

// ...

My query is now:

{where : {aid: aid}, include: this.articleRelations}

But I am getting the following error:

{
code : "ER_BAD_FIELD_ERROR",
errno : 1054,
sqlState : "42S22",
index : 0,
sql : "SELECT `item`.*, `Parent`.`aid` AS `Parent.aid`, `Parent`.`gid` AS `Parent.gid`, `Parent`.`title` AS `Parent.title`, `Parent`.`type` AS `Parent.type`, `Parent`.`parentAid` AS `Parent.parentAid`, `Parent`.`createdAt` AS `Parent.createdAt`, `Parent`.`updatedAt` AS `Parent.updatedAt`, `Parent`.`itemId` AS `Parent.itemId`, `Parent`.`aid` AS `Parent.aid`, `Parent`.`aid` AS `Parent.aid`, `Parent`.`aid` AS `Parent.aid`, `Children`.`aid` AS `Children.aid`, `Children`.`gid` AS `Children.gid`, `Children`.`title` AS `Children.title`, `Children`.`type` AS `Children.type`, `Children`.`parentAid` AS `Children.parentAid`, `Children`.`createdAt` AS `Children.createdAt`, `Children`.`updatedAt` AS `Children.updatedAt`, `Children`.`itemId` AS `Children.itemId`, `Children`.`aid` AS `Children.aid`, `Children`.`aid` AS `Children.aid`, `Children`.`aid` AS `Children.aid` FROM (SELECT `item`.* FROM `item` WHERE `item`.`aid`=2 LIMIT 1) AS `item` LEFT OUTER JOIN `item` AS `Parent` ON `Parent`.`aid` = `item`.`parentAid` LEFT OUTER JOIN `item` AS `Children` ON `item`.`aid` = `Children`.`itemId`;"

}

Note: * The table name is item * The query contains itemId , which I did not define anywhere. That seems to be a bug?

For reference, this is my model:

ItemModel = sequelize.define('ExerciseItem', {
        aid: {type: Sequelize.INTEGER.UNSIGNED, primaryKey: true, autoIncrement: true},
        gid: {type: Sequelize.INTEGER.UNSIGNED},
        title: Sequelize.STRING(100),
        type: Sequelize.INTEGER.UNSIGNED,
        parentAid: Sequelize.INTEGER.UNSIGNED
    },{
        freezeTableName: true,
        tableName: 'item'
});
Item.find({where : {aid: aid}, include: [{ model: Item, as: 'Parent' }])

If you give the relation an alias, you have to provide that alias when doing eager loading (just like you would call getParent instead of getItem on an item instance)

This is because aliasing (using as ) allows you to create several associations to the same model, so when you just provide the model there is no way for sequelize to know which model you actually want to load.

We have been talking about the ability to using the return value from the relation call instead, something like:

var itemParentRelation = Item.hasOne(Item, { foreignKey: 'parentAid', as: 'Parent' })
Item.find({where : {aid: aid}, include: [itemParentRelation])
// or
Item.find({where : {aid: aid}, include: [item.relations.parent])

But for now you'll have to use the code provided in the beginning of the post :)

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