带有sequelize的graphql连接外键

时间:2018-07-04 02:59:38

标签: sequelize.js graphql

我用graphql制作了简单的Board api系统。

我使用sequelize(版本4)连接数据库。

[schema.graphql]

buffer

[resolvers.js]

type Article {
    article_no: Int!
    subject: String!
    content: String!
    createdAt: String!
    updatedAt: String!
    comment: String
}

type Comment {
    article_no: Int!
    content: String!,
    createdAt: String!
}

type Query {
    articles: [Article]!
    article(article_no: Int!): Article
    comments: [Comment]!
    comment(article_no: Int!): Comment
}

type Mutation {
    createArticle(subject: String!, content: String!, password: String!): Boolean!
    createComment(article_no: Int!, content: String!, password: String!): Boolean!
}

[db.js]

import { Article, Comment } from './db';

const resolvers = {
    Query: {
        articles: async () => {
            return Article.all();
        },
        article: async(_, args) => {
            return Article.find({
                where: args.article_no,
            });
        },
        comments: async () => {
            return Comment.all();
        },
        comment: async(_, args) => {
            return Comment.find({
                where: args.article_no
            });
        }
    },
    Mutation: {
        createArticle: async (_, args) => {
            try {
                const article = await Article.create({
                    subject: args.subject,
                    content: args.content,
                    password: args.password
                });
                return true;
            } catch(e) {
                return false;
            }
        },
        createComment: async(_, args) => {
            try {
                const comment = await Comment.create({
                    article_no: args.article_no,
                    content: args.content,
                    password: args.password
                })
                return comment;
            } catch(e) {
                return false;
            }
        }
    }
}

export default resolvers;

const Sequelize = require('sequelize'); import config from '../config/config'; const db = new Sequelize(config.DB, config.USER, config.PASS, { host: 'localhost', dialect: 'mysql' }) export const Article = db.define('article', { article_no: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, subject: { type: Sequelize.STRING(30), allowNull: false }, content: { type: Sequelize.STRING(100), allowNull: false }, password: { type: Sequelize.STRING(20), allowNull: false }, comment: Sequelize.STRING }, { freezeTableName: true, timestamps: true, underscored: true }) export const Comment = db.define('comment', { content: { type: Sequelize.STRING(150), allowNull: false }, password: { type: Sequelize.STRING(20), allowNull: false }, }, { freezeTableName: true, timestamps: true, underscored: true }) Article.hasMany(Comment, { foreignKey: 'article_no', scope: { comment: 'comment' } }) Comment.belongsTo(Article, { foreignKey: 'article_no', targetKey: 'article_no', allowNull: false, as: 'comment' }); db.sync() .then(console.log('[*] DB Sync Done')) Article是1:N分配。

因此,我将Comment设置为hasMany,并将Article设置为belongsTo

也可以评论作为评论,并将其包括在Article的范围内。

但是当我请求查询Comment时,

评论返回空值。

我引用了文档http://docs.sequelizejs.com/manual/tutorial/associations.html#foreign-keys,并且也照做了。

但这不起作用。

我的预期结果在这里:

{ article(id:1) { subject, comment } }

当前结果在这里:

{
  "data": {
    "article": {
      "subject": "test",
      "comment": {
           "article_no":1,
           "content: "first comment",
           "created_at": "2018010101001",
           # every comment related article is here
      }
    }
  }
}

我想显示与特定文章相关的所有评论。

对此有什么解决办法吗?

谢谢。

2 个答案:

答案 0 :(得分:2)

笔记组,使您走上正轨:

定义关系时,请记住,要调用其方法的模型是您要有效地向其添加属性的模型。例如,如果您调用Article.hasMany(Comment),这将在comments模型上创建Article属性,并会影响Comment模型。同样,调用Comment.belongsTo(Article)将在article模型上创建Comment属性,并且不会影响Article模型。

请注意,即使创建了关系,如果要在查询文章时包括个相关注释(反之亦然),则必须传递适当的include选项。这可以直接在查询调用中完成,即

Article.findAll({ include: [Comment] })

或可以是范围的一部分,例如默认范围。范围可以设置为模型定义的一部分,也可以在事后通过调用addScope添加。例如,您可以这样做:

Article.addScope('defaultScope', {
  include: [Comment],
}, { override: true })

注意:此处的override是必需的,因为默认范围已经存在。要查询关联的模型,您的查询调用或所使用的范围必须包含适当的include数组。关联也有“范围”的概念,但这与模型的范围不同。有关差异的讨论,请参见文档here

最后,在向where调用传递find选项时,应确保它包含要查询的属性名称,即

Article.find({ where: { article_no: args.article_no } })

// or possibly even
Article.find({ where: args })

答案 1 :(得分:0)

您的graphql模式和后继模式存在问题...

让我们看看您的graphql模式

type Article {
    ...
    comment: String
}

您写道文章和评论具有1:M关系 但是这里的注释字段是字符串类型,甚至不是字符串数组

Article的正确类型定义应为(imo):

type Article {
    ...
    comments: [Comment] 
}

现在是否对@ Daniel-Rearden的续集架构进行调整 在他的回答中写道,您的Article模型应该具有comments属性,因此默认情况下它将从default resolver类型的Article返回