【问题标题】:Sequelize Many to Many failing with 'is not associated to' when trying to associate entries?Sequelize Many to Many 在尝试关联条目时以“未关联到”失败?
【发布时间】:2018-09-12 19:54:34
【问题描述】:

我在使用 Sequelize 的多对多配置时遇到问题,它抱怨 site_article_keyword is not associated to article_keyword。下面的代码代表一个最小的测试用例,试图理解我做错了什么(我希望提供更小的东西,但这就是我所拥有的)。我将 bluebird 用于 Promise API。

const Sequelize = require('sequelize');

var sequelize = new Sequelize(undefined, undefined, undefined, {
    dialect: 'sqlite',
    storage: './mydatabase',
});

const SiteArticle = sequelize.define('site_article', {
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    ownerId: {
        type: Sequelize.INTEGER,
        field: 'owner_id'
    },
    title: Sequelize.STRING
        // other fields omitted
}, {
    timestamps: true
});

const ArticleKeyword = sequelize.define('article_keyword', {
    id: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    name: Sequelize.STRING,
    language: Sequelize.STRING
        // other fields omitted
}, {
    timestamps: true
});

const SiteArticleKeyword = sequelize.define('site_article_keyword', {
    siteArticleId: {
        type: Sequelize.INTEGER,
        field: 'site_article_id',
        references: {
            model: SiteArticle,
            key: 'id'
        }
    },
    articleKeywordId: {
        type: Sequelize.INTEGER,
        field: 'article_keyword_id',
        references: {
            model: ArticleKeyword,
            key: 'id'
        }
    }
    // other fields omitted
}, {
    timestamps: true
});

(ArticleKeyword).belongsToMany(
    SiteArticle, { through: SiteArticleKeyword });

(SiteArticle).belongsToMany(
    ArticleKeyword, { through: SiteArticleKeyword });

这是定义的模型,现在用于尝试创建源条目和目标条目,然后我想要关联它们。失败发生在我调用ArticleKeyword.findAll()的那一行:

sequelize.sync({}).then(function() {

    // populate some data here

    let siteArticle;

    SiteArticle.create({
        ownerId: 1,
        title: 'hello world'
    }).then(function(entry) {
        siteArticle = entry;
        console.log('site article: ', JSON.stringify(entry, undefined, 2));

        return ArticleKeyword.findOrCreate({
            where: {
                name: 'keyword1',
                language: 'en'
            }
        });
    }).spread(function(entry, success) {
        console.log('article keyword: ', JSON.stringify(entry, undefined, 2));
        return siteArticle.addArticle_keyword(entry);
    }).spread(function(entry, success) {
        console.log('site article keyword: ', JSON.stringify(entry, undefined, 2));

        const siteArticleId = 1;
        const language = 'en';

        return ArticleKeyword.findAll({
            where: {
                language: language,
            },
            include: [{
                model: SiteArticleKeyword,
                where: {
                    siteArticleId: siteArticleId
                }
            }]
        });
    }).then(function(articleKeywords) {
        if (articleKeywords) {
            console.log('entries: ', JSON.stringify(articleKeywords, undefined, 2));
        } else {
            console.log('entries: ', 'none');
        }
    }).catch(function(error) {
        console.log('ERROR: ', error);
    }.bind(this));

}).catch(function(error) {
    console.log(error);
});

我的代码基于 Sequelize 文档中的“Mixin BelongsToMany”示例。

谁能建议我做错了什么?

【问题讨论】:

    标签: node.js sequelize.js


    【解决方案1】:

    问题原来site_article_keyword没有关联的原因是因为它是关联!考虑到这一点,代码变为:

    return ArticleKeyword.findAll({
        where: {
            language: language,
        },
        include: [{
                model: SiteArticle,
                as: 'SiteArticle',
                siteArticleId: siteArticleId
            }]
        });
    

    顺便说一句,对我的代码的一个小调整是在 belongsToMany 中包含“as”:

    ArticleKeyword.belongsToMany(
        SiteArticle,
        { through: SiteArticleKeyword, as: 'SiteArticle' }
    );
    
    SiteArticle.belongsToMany(
        ArticleKeyword,
        { through: SiteArticleKeyword, as: 'ArticleKeyword' }
    );
    

    这允许addArticleKeyword() 而不是addArticle_Keyword()

    【讨论】:

    • 有没有办法做到这一点不必在模型和查询中都指定“as”?似乎是多余的,现在我们在两个地方留下了一个硬编码的字符串。
    【解决方案2】:

    在通过关系中,以下应该起作用

    ArticleKeyword.findAll({
      include: [{
        model: SiteArticle,
        through: {
          attributes: ['createdAt', 'startedAt', 'finishedAt'],
          where: {siteArticleId: siteArticleId
        }
      }]
    });
    

    【讨论】:

    • 这个“site_article_keyword is not associated to article_keyword”?
    • 是的,我想我已经找到了答案。将在答案中详细说明。
    猜你喜欢
    • 1970-01-01
    • 2020-07-01
    • 2021-02-02
    • 2017-07-31
    • 2016-11-05
    • 2014-06-22
    • 1970-01-01
    • 2016-09-05
    • 1970-01-01
    相关资源
    最近更新 更多