对应内容:#6 Adding Relations | Build a Complete App with GraphQL, Node.js, MongoDB and React.js
这一节主要干了下面的事:
- 安装bcryptjs,并导入
- 为User和Event创建关系
- 1.创建了User模型,并在User中添加了和Event的关系
- 2.修改了Event模型,并添加外键User.id
- 在app.js中修改Schema,添加User和UserInput两种type
- 添加了两个模型之间的关系后,创建时也需要调整逻辑以创建联系,大量修改Event和User在创建到数据库时的逻辑
1 创建User
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const userSchema = new Schema({
email: {
type: String,
require: true
},
password: {
type: String,
require: true
},
createEvents: [
{
type: Schema.Types.ObjectId,
// Event注意大小写
// 外键?
ref: "Event"
}
],
})
module.exports = mongoose.model("User", userSchema);
2 修改Event Model
创建creator,表示该Event是哪个User创建的。
...
date: {
type: Date,
required: true
},
creator: {
type: Schema.Types.ObjectId,
// User注意大小写
ref: "User"
}
修改Schema
大多时候我们其实不希望User的返回值中有password,因此不加感叹号 !
。
type User {
_id: ID!
email: String!
password: String
}
input UserInput {
email: String!
password: String!
}
type RootMutation {
createEvent(eventInput: EventInput): Event
+> createUser(userInput: UserInput): User
}
修改模型创建时的逻辑
安装bcryptjs,并导入
cnpm install --save bcryptjs
createEvent: args => {
const event = new Event({
title: args.eventInput.title,
description: args.eventInput.description,
price: +args.eventInput.price,
date: new Date(args.eventInput.date),
creator: "60434731671d8120f059f127"
})
let _event;
return event.save()
.then(result => {
// 这里这么做的原因是底下返回的result是user.save()的结果,是user的_doc,而本函数原始的目的是返回event创建的结果,因此要特殊处理
_event = {
...result._doc,
id: result.id
}
console.log(result);
return User.findById(result.creator);
})
.then(user => {
if (!user) {
throw new Error("user do not existed");
} else {
console.log(user);
// 这里理论上只需要一个Event id,但如果我们传递整个event进去,mongoose也能正确处理
user.createEvents.push(event);
return user.save();
}
})
.then(result => {
return _event;
})
.catch(err => {
throw err;
});
},
createUser: args => {
return User.findOne({ email: args.userInput.email })
.then(user => {
// 不论user存在与否,都会fulfilled并返回user
// 除非,发生网络错误,数据库连接错误等,才会rejected
if (user) {
throw new Error("user already existed");
} else {
return bcrypt.hash(args.userInput.password, 12);
}
})
.then(hashedPassword => {
const user = new User({
email: args.userInput.email,
password: hashedPassword,
})
return user.save();
})
.then(result => {
return {
...result._doc,
_id: result.id,
// 为了安全起见,这里返回null去代替password
password: null
}
})
.catch(err => {
throw err;
})
}