我用graphql制作了简单的板子api系统 .
我使用sequelize(版本4)连接数据库 .
[schema.graphql]
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!
}
[resolvers.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;
[db.js]
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
和 Comment
是1:N的关系 .
所以我将 hasMany
设置为 Article
并将 belongsTo
设置为 Comment
.
同时评论为评论并将其包含在文章的范围内 .
但是当我请求查询 { article(id:1) { subject, comment } }
时,
注释返回null .
我参考文档http://docs.sequelizejs.com/manual/tutorial/associations.html#foreign-keys并遵循 .
但它不起作用 .
我的预期结果如下:
{
"data": {
"article": {
"subject": "test",
"comment": {
"article_no":1,
"content: "first comment",
"created_at": "2018010101001",
# every comment related article is here
}
}
}
}
目前的结果如下:
{
"data": {
"article": {
"subject": "test",
"comment": null
}
}
}
我想显示与特定文章相关的所有评论 .
对此有什么解决方案吗?
谢谢 .
2 回答
几个笔记让你走在正确的轨道上:
在定义关系时,请记住,您调用其方法的模型是您实际添加属性的模型 . 例如,如果调用
Article.hasMany(Comment)
,这将在Article
模型上创建comments
属性,并将影响Comment
模型 . 同样,调用Comment.belongsTo(Article)
将在Comment
模型上创建article
属性,而不会影响Article
模型 .请注意,即使创建了关系,如果要在查询文章时包含关联的注释(反之亦然),则必须传入相应的
include
选项 . 这可以直接在查询调用中完成,即或者可以是范围的一部分,例如默认范围 . 范围可以设置为模型定义的一部分,也可以在事后通过调用
addScope
添加 . 例如,您可以这样做:注意:此处需要
override
,因为默认范围已存在 . 要查询关联的模型,您的查询调用或您正在使用的范围必须包含相应的include
数组 . 协会也有"scope"的想法,但它的范围是_2895128 . 有关差异的讨论,请参阅文档here .最后,当您将
where
选项传递给find
调用时,您应该确保它包含您要查询的属性名称,即您的graphql架构和续集架构存在问题......
让我们看看你的graphql架构
你写的文章和评论有1:M的关系,但这里的注释字段是字符串类型,甚至不是字符串数组
文章的正确类型定义应该是(imo):
现在如果你对你的续集模式进行调整@ Daniel-Rearden在他的回答中写道你的
Article
模型应该有一个comments
属性,所以默认情况下会从Article
类型的default resolver
返回