Aaron Balthaser
Aaron Balthaser

Reputation: 2644

Sequelize: is there a way to update a value from an instance method

Im am trying to add a value to a column after an account is created and I would like to do this from the instance method of the model. I am creating the account in a service in the typical manner and I want to use the users id which is generated by sequelize to concat to another generated id which is also stored in the Users table with each user. I basically would like to call the instance method once the user is created as follows:

Model:

module.exports = function(sequelize) {

  let User = sequelize.define('User', {
    email: ORM.STRING,
    password: ORM.STRING,
    accountVerified: {
      type: ORM.INTEGER,
      defaultValue: 0
    }
  },
  {
    classMethods: {
      hashPassword: function(password) {
        return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
      }
    },
    instanceMethods: {
      validatePassword: function(password) {
        return bcrypt.compareSync(password, this.password);
      },
      uniqueId: function() {
        let ch = this.id + sid.generate();
        this.userId = this.id + sid.generate();
      }
    }
  });

  return User;
};

Service:

findOrCreate(email, password, done) {
  let cachedEmail = email;

  this.models.User
    .findOrCreate({
      where: { email: email },
      defaults: {
        password: this.models.User.hashPassword(password)
      }
    })
    .spread(function(user, created) {
      if (!created) {
        return done(null, false, {
          email: cachedEmail,
          message: `Email ${cachedEmail} already exists.`
        });
      }
      user.uniqueId();
      done(null, user);
    });
}

Upvotes: 0

Views: 1540

Answers (1)

piotrbienias
piotrbienias

Reputation: 7401

You can do it in two ways

  • use afterCreate hook which is run immediately after creating new instance,
  • use the instance method which updates specified column value.

The first option is very comfortable because it is run every time new instance of model is created so you would not have to remember about adding the code every time you would like to generate the unique id.

{
    hooks: {
        afterCreate: function(user, options){
            let uniqueId = user.get('id') + sid.generate();
            return user.set('userId', uniqueId).save().then((self) => {
                return self;
            });
        }
    }
}

Above code would simply execute UPDATE on newly created user instance.

On the other hand, if you want to use instance method, it should look like that

{
    instanceMethods: {
        uniqueId: function() {
            let uniqueId = this.get('id') + sid.generate();
            return this.set('userId', uniqueId).save().then((self) => {
                return self;
            });
        }
    }
}

And then you could call it as normal instance method, however it returns a promise

userInstance.uniqueId().then((user) => {
    // updated user
    done(null, user);
}).catch(e => {
    // handle error
    done(e);
});

Upvotes: 1

Related Questions