Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequelize, custom setter, doesn't set

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?

like image 928
Brett Wagner Avatar asked Feb 25 '14 01:02

Brett Wagner


1 Answers

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);
        }
    }
})
like image 122
sdepold Avatar answered Nov 02 '22 21:11

sdepold