For my email field, I store and query emails as lowercase strings to avoid duplicate emails like user@example.com and User@example.com. I have a set method defined in my model like:
const User = sequelize.define('user', {
email: {
type: DataTypes.STRING,
unique: { msg: 'That email is already registered.' },
validate: { isEmail: { msg: 'Invalid email.' } },
set(value) {
this.setDataValue('email', value.toLowerCase().trim())
}
}
})
This prevents setting emails with uppercase letters, but it does not prevent queries with uppercase letters. To avoid queries, I have to remember to use .toLowerCase() everywhere. It would be better if I could define it on the model so that a query like this would just work:
const user = await User.findOne({ where: { email: 'SomeEmail@example.com' } })
You can use the hooks in models to store the email in lower case.
Please have a look in below example
const createUserModel = (sequelize, { STRING, UUIDV4, UUID, DATE }) => {
const User = sequelize.define(
'User',
{
userId: {
type: UUID,
defaultValue: UUIDV4,
primaryKey: true,
},
email: {
type: STRING,
allowNull: false,
unique: true,
validate: {
isEmail: true,
},
},
password: {
type: STRING,
allowNull: true,
},
},
{
freezeTableName: true,
timestamps: false,
hooks: {
beforeCreate: async instance => {
const email = instance.get('email');
instance.set('email', email.toLowerCase());
},
beforeUpdate: async instance => {
if (instance.changed('email')) {
const email = instance.get('email');
instance.set('email', email.toLowerCase());
}
},
},
},
);
return User;
};
module.exports = {
createUserModel,
};