Nodejs and Mysql: Query 3 columns

Asked

Viewed 217 times

-2

I need to make sure that the user will not be able to register the registration: email, cpf or cnpj again. I have a code, which I can restrict email. How to implement the code to check in the table the 3 columns simultaneously? Follows the code:

router.post("/registro", (req, res) => {
   var erros = []

   if(!req.body.nome || typeof req.body.nome == undefined || req.body.nome == null){
      erros.push({texto: "Nome inválido"})
   }

   if(!req.body.email || typeof req.body.email == undefined || req.body.email == null){
      erros.push({texto: "E-mail inválido"})
   }

   if(!req.body.pwd || typeof req.body.pwd == undefined || req.body.pwd == null){
      erros.push({texto: "Senha inválida"})
   }

   if(req.body.pwd.length < 4 ){
      erros.push({texto: "Senha muito curta"})
   }

   if(req.body.pwd != req.body.pwd2){
      erros.push({texto: "As senhas são diferentes, tente novamente!"})
   }

   if(erros.length > 0){

      res.render("usuarios/registro", {erros: erros})

   }else{

        //Verificações:
        //(d1)-Verificando o usuário pelo e-mail // ok
        //(d2)-Verificar o usuário pelo cpf      // falta
        //(d3)-Verificar o usuário pelo cnpj     // falta


      Usuario.findOne({where:{email: req.body.email}}).then((d1) => {
         if(d1){
           req.flash("error_msg", "Já existe uma conta com este e-mail no nosso sistema")
           res.redirect("/usuarios/registro")

      (verificações...)


   }else{

      const novoUsuario = new Usuario({
                   nome: req.body.nome,
                   email: req.body.email,
                   pwd: req.body.pwd,
                   cpf: req.body.cpf,
                   cnpj: req.body.cnpj

                 })

                    bcrypt.genSalt(10, (erro, salt) => {
                    bcrypt.hash(novoUsuario.pwd1, salt, (erro, hash) => {
                    if(erro){
                      req.flash("error_msg", "Houve um erro durante o salvamento do usuário")
                      res.redirect("/usuarios/registro")
                 }
                    //Se passar pela validação e tudo estiver correto então cria o novoUsuario
                    novoUsuario.pwd = hash

                    novoUsuario.save().then(() => {
                    req.flash("success_msg", "Usuário criado com sucesso!")
                    res.redirect("/msgret")

                   }).catch((err) => {
                    req.flash("error_msg", "Houve um erro ao criar o usuário, tente novamente!")
                    res.redirect("/usuarios/registro")
                  })
               })
            })
         }

      }).catch((err) => {  
          req.flash("error_msg", "Houve um erro interno")
          res.redirect("/")
      })
   }
})

If it does not find in the table the email, cpf or cnpj, then save the new user.

2 answers

0

The simplest way is to declare these attributes in the model as being unique, for example:

const Usuario = sequelize.define("usuario", {
  email: {
    type: DataTypes.TEXT,
    allowNull: false,
    unique: true // Aqui você indica que o valor não pode ser repetido
  }
});

With the unique, while trying to realize a .create(), Sequelize will make an exception UniqueConstraintError:

try {
  Usuario.create(usuario);
} catch (error) (
  if (error instanceof Sequelize.UniqueConstraintError) {
    // Erro UniqueConstraintError
  } else {
    // Outro erro qualquer
  }
}

Or

Usuario.create(usuario).then((usuarioCriado) => {
  // Deu certo
}).catch(Sequelize.UniqueConstraintError, (error) => {
  // Aqui entrará somente o erro UniqueConstraintError
}).catch(error => {
  // Aqui entra qualquer erro
});

But to make a findOne via code is very simple, using the Op.or he will try to find a Usuario which meets any of the conditions:

Usuario.findOne({
  where: {
    [Op.or]: [ 
      { email: req.body.email },
      { cpf: req.body.cpf }, // Não sei como está no seu modelo, mas esse é o raciocínio
      { cnpj: req.body.cnpj }
    ]
  }
});
  • Bacana Rafael. And the "error_msg" can be implemented in the same model ?

  • If you choose to unique, you can try to do the .create() within a try catch. Sequelize will throw an error if the value is repeated and you can use the error_msg ali. If you choose the second option, it is the same reasoning you are currently having in the question code.

  • @Cleytonramos edited the answer with the example content the error and reference to the documentation :)

  • Wonder! It’s clearing the mind.

  • Thanks for the support Rafael. I will implement the code here.

  • I’m not getting it. Where do I put the whole code here? I’d like to check before creating the new user.

  • Just replace the where of your code for what I put here with the Op.or. Take a look at the links that have more examples

  • I’ll re-edit all the code so you can analyze it in full.

Show 3 more comments

0

One way to put this validation is to do it via database, just configure the respective columns to be of the Unique type. By entering the database will already do this validation for you. You can look how to put this restriction

In the definition of your model just put the following attribute allownull: false and attribute unique: true:

//jshint esversion: 6

export default (sequelize, DataType) => {
  const User = sequelize.define('User', {
    id: {
      type: DataType.INTEGER,
      autoIncrement: true,
      primaryKey: true
    },
    name: {
      type: DataType.STRING,
      allowNull: false
    },
    email: {
      type: DataType.STRING,
      allowNull: false,
      unique: true
    },
    cpf: {
      type: DataType.STRING,
      allowNull: false,
      unique: true
    },
    login: {
      type: DataType.STRING,
      allowNull: false,
      unique: true
    },
    freezeTableName: true,
    tableName: 'users'
  });

  return User;
};
  • Cool! Danizavtz! thanks for the support.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.