如何使用猫鼬为用户分配用户角色

Posted

技术标签:

【中文标题】如何使用猫鼬为用户分配用户角色【英文标题】:How to assign user's role for a user using mongoose 【发布时间】:2021-12-30 08:57:38 【问题描述】:

我有两个架构 UserSchemaRoleTypeSchema 。在UserSchema 中,我添加了一个字段UserRoleType,即ref RoleTypeSchema。我要做的是在RoleTypeCollection 中创建roleType,然后当我在UserCollection 中创建UserObject 时,我可以在UserCollection 中看到UserRoleType 字段。

The error that i am getting is after i create the role and user, when i get an error validation:

THE ERROR

"message":"userSchema validation failed: usersRoles: Path `usersRoles` is required."

UserSchema

    //requiring the mongoose module 
const mongoose = require('mongoose');

// create the schema 
var userSchema = new mongoose.Schema(

    //creating the attributes/ data of the schema

    username: 
        type: String,
        required: true
    ,

    password: 
        type: String,
        required: true
    ,

    usersRoles: 
        type: mongoose.Schema.Types.ObjectId,
        ref: 'usersRolesSchema',
        required: true
    

);


const userDB = mongoose.model('userSchema', userSchema);

module.exports = userDB;

RoleTypeSchema

 //requiring the mongoose module 
const mongoose = require('mongoose');



var usersRolesSchema = new mongoose.Schema(

    userRole: 
        type: String,
        required: true
    

)

const userRolesModel = mongoose.model('usersRolesSchema', usersRolesSchema);

module.exports = userRolesModel;

Create A User Controller

 exports.createUser = (req, res, next) => 

    console.log('Post CREATE User /create-user');

    // getting the request body
    const username = req.body.username;
    const userRole = req.body.userRole;
    const password = req.body.password;
    const password2 = req.body.password2;

    // check the body request by using express validator
    req.checkBody('username', 'UserName is required').notEmpty();
    req.checkBody('userRole', 'userRole is required').notEmpty();
    req.checkBody('password', 'Password is required').notEmpty();
    req.checkBody('password2', 'UserName is required').equals(req.body.password);
    // get the error if there are any 
    let errors = req.validationErrors();

    //validation for duplicate values
    if (errors) 

        userSchema.findOne( username: req.body.username )
            .then(user =>  //that's will give us the user and then i want to check if 

                if (user) 
                    //if there is an error so rerinder the templet
                    res.render('users/create_user.ejs', 
                        errors: errors //pass along the errors
                    , console.log(errors));
                

            );

     else 
        let newUser = new userSchema(
            username: username, // first is the attribute NAME of the model , second is the name value tag in the html file
            userRole: userRole,
            password: password
        );

        bycrypt.genSalt(10, function(err, salt) 
            bycrypt.hash(newUser.password, salt, function(err, hash) 
                if (err) 
                    //ERROR PAGE
                    console.log(err);
                

                /// Hashing the password
                newUser.password = hash;

                newUser.save()
                    .then(data => 
                        if (err) 
                            console.log(err);
                            return;
                         else 
                            req.flash('success', 'You successfully registered')
                            res.redirect('/halalMunchies/all-users');
                        
                    )
                    .catch(err => 
                        res.status(500).send(
                            message: err.message || "Some error occured while creating a create operation"
                        );
                    );


            );
        );
    


;

Showing All Users Data, which here it should show the userType also

    exports.allUsers = (req, res, next) => 

    console.log('GET CREATE USERS /all-users');


    userSchema.find().populate('usersRoles', 'userRole')
        .then(data => 
            res.render('users/users.ejs',  usersList: data );
            console.log();
        )
        .catch(err => 
            console.log(err);
        )


;

The creating userForm, in this form i will select the userRole and i can use req.body to that name tag so i can use it and save it like a username or password input

<label> User Type: </label>

<select class="form-control form-control-sm" id="roles" name="userRole">
    <option value="" selected data-default> Select Role </option>
        <% roles.forEach(function (role) %>
        <option> <%= role.userRole %> </option>

        <%)%>

    </select>


<br>

【问题讨论】:

【参考方案1】:

在你的 userSchema 上你已经定义了这个

 usersRoles: 
    type: mongoose.Schema.Types.ObjectId,
    ref: 'usersRolesSchema',
    required: true

但是当您创建一个用户时,您不会将 userRoles 传递给它。

您需要创建一个新的 usersRolesSchema,然后在创建新用户时将其 id 分配给用户

newUser = new userSchema(
        username: username, // first is the attribute NAME of the model , second is the name value tag in the html file
        userRole: userRoleID,
        password: password,
        userRoles: "id"
    );

或者您可以从 userSchema 中的 usersRoles 字段中删除必填字段

【讨论】:

能否显示我如何将角色的 id 分配给用户,我无法删除此字段,因为我需要显示用户的角色 @HeshamEldawy see newUser = new userSchema( username: username, //第一个是模型的属性NAME,第二个是html文件中的name值标签 userRole: userRoleID, password: password,用户角色:“id”);之后调用保存 userRoleID 指的是什么?对于 userRoles : "id" ,这里的 id 是一个字符串值。 嗯,它指的是你应该根据你的流程创建的这个表 var usersRolesSchema = new mongoose.Schema( userRole: type: String, required: true ) newUserRole = new userRole(用户角色:“新角色”); newUserRole.save() newUser = new userSchema( username: username, // 第一个是模型的属性NAME,第二个是html文件中的name值标签 userRole: newUserRole._id, password: password, userRoles: "id " ); newUser.save() 非常感谢您的帮助,但我厌倦了尝试所有希望正确的解决方案,所以您能否请您添加将运行代码的答案,然后我会理解一切

以上是关于如何使用猫鼬为用户分配用户角色的主要内容,如果未能解决你的问题,请参考以下文章

在 mongoose 中为用户分配角色

猫鼬为未知键定义模式

如果用户角色(卖家与买家)有所不同,我该如何构建我的猫鼬模式?

猫鼬为未知密钥定义架构

如何使用mongodb使用特定键加入多个集合?

如何使用 laravel 8 +jetstream + spatie 为注册用户分配角色