Graphql 初体验 第四章 | #6 Adding Relations

对应内容:#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;
        })
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值