Question

Unfortunatly the documentation for model property setters and getters is somewhat deficient and I'm having trouble getting my little setter to work.

var bcrypt = require('bcrypt');

module.exports = function( sequelize, DataTypes )
{
    var User = sequelize.define('User', {
        username:       { type:DataTypes.STRING, unique: true, allowNull: false },
        email:          { type:DataTypes.STRING, allowNull: false, unique: true },
        userlevel:      { type:DataTypes.INTEGER, allowNull:false, defaultValue:0 },
        password:       { type:DataTypes.STRING, 
            set: function(v) {
                var pw = this;
                var r;
                bcrypt.genSalt(10, function(err,salt) {
                    bcrypt.hash(v, salt, function(err,hash) {
                        pw.setDataValue('password', hash);
                    });
                });
            } }
    });



    return User;
}

Now from what I can tell based on github issues custom setters on properties are not called on create() so calling

db.User.create( { username:'guest', email:'guest@guest', userlevel:1, password:'guest' } ).success( function(record) { console.log(record) });

results in the following insert:

Executing (default): INSERT INTO `Users` (`id`,`username`,`email`,`userlevel`,`createdAt`,`updatedAt`) VALUES (DEFAULT,'guest','guest@guest',100,'2014-02-25 01:05:17','2014-02-25 01:05:17');

so I went ahead and added the following in the success clause:

u.set('password', 'stupid');
u.save();

I can see that my setter is getting properly called and that the hash is getting set on the password property. However once the setter ends and I return back to my u.save() line the u object is back to it's previous state with no password set.

Any ideas?

Was it helpful?

Solution

You are experiencing this issue, because getters and setters are currently only support synchronous actions. Saying this, you can find a working solution here:

var User = sequelize.define('User', {
    username:       { type: DataTypes.STRING,  allowNull: false, unique: true   },
    email:          { type: DataTypes.STRING,  allowNull: false, unique: true   },
    userlevel:      { type: DataTypes.INTEGER, allowNull:false,  defaultValue:0 },
    password:       {
        type: Sequelize.STRING,
        set:  function(v) {
            var salt = bcrypt.genSaltSync(10);
            var hash = bcrypt.hashSync(v, salt);

            this.setDataValue('password', hash);
        }
    }
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top