对应内容:#8 Adding Bookings | Build a Complete App with GraphQL, Node.js, MongoDB and React.js
之前我们创建了User和Event模型,并在他们之间建立了动态的查询关系(可以无限嵌套),今天主要是添加一个Booking模型,以建立User和Event之间的联系。
主要内容:
- 创建./model/booking.js
- 修改对应的Schema模板
- 在rootValue中增加对应的功能,建立对应的resolver
- 提供查询booking,删除booking,创建booking三个功能
1 创建booking model
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const bookingSchema = new Schema(
{
event: {
type: Schema.Types.ObjectId,
ref: "Event",
},
user: {
type: Schema.Types.ObjectId,
ref: "Event",
},
}, {
timestamps: true
}
);
module.exports = mongoose.model("Booking", bookingSchema);
2 修改对应的Schema,创建功能
+>
表示新加的行
module.exports = buildSchema(`
type Booking {
_id: ID!
event: Event!
user: User!
createdAt: String!
updateAt: String!
}
...
type RootQuery {
events: [Event!]!
+>bookings: [Booking!]!
}
type RootMutation {
createEvent(eventInput: EventInput): Event
createUser(userInput: UserInput): User
+>bookEvent(eventId: ID!): Booking!
+>cancelBooking(bookingId: ID!): Event!
}
...
3 在rootValue中创建对应的resolver
创建独立函数getSingleEvent
,通过eventId
获得单个event
const getSingleEvent = async eventId => {
try {
const event = await Event.findById(eventId);
return {
...event._doc,
creator: getUserById(event.creator)
}
} catch (error) {
throw error;
}
}
在rootValue
中创建booking
函数
在rootValue
中创建bookEvent
函数
在rootValue
中创建cancelBooking
函数
我们在Schema的模板字符串中创建了哪些函数的定义,这里就要实现哪些函数,这是一一对应的。
const rootValue = {
...
bookings: async () => {
try {
const bookings = await Booking.find();
return bookings.map(booking => {
return {
...booking._doc,
user: getUserById(booking.user),
event: getSingleEvent(booking.event),
createdAt: booking.createdAt.toISOString(),
updatedAt: booking.updatedAt.toISOString(),
}
})
} catch (error) {
throw error;
}
},
...
bookEvent: async args => {
const fetchedEvent = await Event.findById(args.eventId);
const booking = new Booking({
// 这里暂时用一个id代替,需要去mongodb atlas中获得。
user: "604482754c6bd70d2453f3e0",
event: fetchedEvent
});
const result = await booking.save();
return {
...result._doc,
user: getUserById(booking.user),
event: getSingleEvent(booking.event),
createdAt: result.createdAt.toISOString(),
updatedAt: result.updatedAt.toISOString(),
}
},
cancelBooking: async args => {
try {
// populate在这里理解为join操作,把此booking关联的event合并入该booking的event属性。
const booking = await Booking.findById(args.bookingId).populate("event");
const event = {
...booking.event._doc,
creator: getUserById(booking.user)
}
await Booking.deleteOne({ _id: args.bookingId});
return event;
} catch (error) {
throw error;
}
}
}