Skip to content

beforeCreate and Model Properties #69

Closed

Description

@markandrus

Hi,

Thanks a lot for this project. I was wondering if I'm doing something wrong here—I expect to be able to modify the properties of a model in beforeCreate, but Postgres shows the following in the database:

 id |        email        | password | salt | created 
----+---------------------+----------+------+---------
  1 | test@email.com      | visible? |      | 
var orm    = require('orm'),
    bcrypt = require('bcrypt');

orm.connect('postgres://localhost/database', function (err, db) {
  var Person = db.define('Person', {
    email: String,
    password: String,
    salt: String,
    created: Date
  }, {
    validations: {
      email: orm.validators.unique()
    },
    hooks: {
      beforeCreate: function () {
        if (!this.salt) {
          console.log('Generating salt...');
          this.salt = bcrypt.genSaltSync(10);
          this.created = new Date();
        }
        if (this.password) {
          console.log('Hashing password...');
          this.password = bcrypt.hashSync(this.password, this.salt);
        }
      }
    }
  });
  // Person.sync(function (err) { console.log(err); });
  Person.create([{
    email: 'test@email.com',
    password: 'visible?'
  }], function (err, items) {
    console.log(err);
    // console.log(items);
  });
});

Testing with beforeSave yields different results for me, too: the password gets hashed, but salt and created go unset in the database.

Activity

  1. markandrus commented on Mar 9, 2013

    @markandrus
    ContributorAuthor

    After looking at /lib/Instance.js, I guess the functionality I'm looking for requires threading data as an argument through the hook.

  2. dresende commented on Mar 9, 2013

    @dresende
    Owner

    Actually, the blame is beforeCreate should be right after/before beforeSave (a few lines above). In that zone, you can use the this context to change the data. I'm going to make this change.

  3. dresende commented on Mar 9, 2013

    @dresende
    Owner

    If you want to test it you have to check the latest git version, it will take some days before pushing a new version. Or you can use the hook beforeSave which should have the same behavior for new instances (but you'll also have it trigger for not new instances).

  4. markandrus commented on Mar 9, 2013

    @markandrus
    ContributorAuthor

    Thanks! I've tested and it works when updating properties enumerated in the call to create, but I can't add properties—for example, to get the above to populate the salt column, I have to change the create call to include that key:

    Person.create([{
      email: 'test@email.com',
      password: 'visible?',
      salt: ''
    }], /* ... */
  5. dresende commented on Mar 11, 2013

    @dresende
    Owner

    Please try it now.

  6. dxg commented on Mar 13, 2013

    @dxg
    Collaborator

    This works however rangeLength validator is checking for undefined, whereas attributes not listed in Person.create[{...}] are now initialised to null and the validation blows up.

    Is it possible for an attribute to ever be undefined? Should the validation only be checking for null, or both null & undefined?

  7. dresende commented on Mar 13, 2013

    @dresende
    Owner

    You're right. To be consistent, it should initialize to undefined.

  8. dresende commented on Mar 13, 2013

    @dresende
    Owner

    I'm going to assume it's fixed. If you have any other problems please reopen or create a new issue :)

  9. markandrus commented on Mar 14, 2013

    @markandrus
    ContributorAuthor

    Just tested--it works! Thanks

  10. added a commit that references this issue on Mar 14, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions