2

I am using waterlock for sails.js to manage my users. I want them to have a unique username so I have this in my User.js:

module.exports = {
  autoPk : false,
  attributes: require('waterlock').models.user.attributes({
    id : {
      type : "string",
      primaryKey : true,
      unique : true
    }
  }),

  beforeCreate: require('waterlock').models.user.beforeCreate,
  beforeUpdate: require('waterlock').models.user.beforeUpdate
};

My Auth.js looks like this:

module.exports = {

  attributes: require('waterlock').models.auth.attributes({
    username : {
      type : "string",
      unique : true
    }
  }),

  beforeCreate: require('waterlock').models.auth.beforeCreate,
  beforeUpdate: require('waterlock').models.auth.beforeUpdate
};

And I am creating users like this:

auth = {
  username: params.username,
  password: params.password
};
userObj = {
  id: params.username
};

User.create(userObj)
  .exec(function (err, user) {
    if (err) {
      sails.log.error("USER: " + err);
      req.session.flash = {
        err: err
      };
      return res.json(err);//res.redirect('/user/create');
    } else {
      req.session.user = user;
      waterlock.engine.attachAuthToUser(auth, user, function (err) {
        if (err) {
          sails.log.error("AUTH: " + err);
          return res.json(err);
        } else {
          req.session.authenticated = true;
          return res.json({ok: true});
        }
      });
    }
  });

Obviously I want the creation of a user to fail when one with the same id already exists. However, the creation of the user works and the creation of the auth fails because of the unique constraint on username. But once this fails I already have two users with the same ID in my database, with no auth attached. Why is this happening? I am using node v0.12.1, sails 0.11 and waterlock 0.14. The adapter I am using is the built-in sails-disk with {migrate : "alter"}. Another strange thing is: When I restart sails, it asks me if it should remove duplicates in the user table. Why does it recognize them then but not when I create the user? Thank you for your help, Alexander

AlexanderF
  • 254
  • 3
  • 11
  • I thought they were unique by default? The sails gitter might be a good place to chat about this: https://gitter.im/balderdashy/sails. – Travis Webb Apr 03 '15 at 23:25
  • Yes, primaryKeys should be unique, I just added the "unique : true" to check if that changes anything... – AlexanderF Apr 04 '15 at 00:41

2 Answers2

1

Maybe you have to add the property migrate : 'drop', to each model, to reload both model. Test one time and then remove the property.

I'm_ADR
  • 1,017
  • 8
  • 15
  • Hi, I tried that, it unfortunately did not work. When I set migrate to 'drop' waterline does not seem to create any indices and therefore does not enforce unique constraints at all. – AlexanderF Apr 07 '15 at 06:30
  • Are you using a database or the local-disk ? – I'm_ADR Apr 07 '15 at 06:35
  • Hi, I use the sails-disk adapter. This adapter previously did not support uniqueness checks, but that feature was added recently. – AlexanderF Apr 07 '15 at 07:05
0

Do that you need to specify it:

module.exports = {
  attributes: {
    username: {
        type: 'string',
        unique: true,
        required: true
    }
  }
};

And you can also do with custom types:

module.exports = {
  types: {
    size: function() {
        true
    }
  },
  attributes: {
    username: {
        type: 'string',
        unique: true,
        minLength: 4,
        macLength: 10,
        size: 10,
        required: true
    }
  }
};

And the response if err:

{
  "error": "E_VALIDATION",
  "status": 400,
  "summary": "2 attributes are invalid",
  "model": "User",
  "invalidAttributes": {
    "username": [
      {
        "rule": "string",
        "message": "`undefined` should be a string (instead of \"null\", which is a object)"
      },
      {
        "rule": "minLength",
        "message": "\"minLength\" validation rule failed for input: null"
      },
      {
        "rule": "required",
        "message": "\"required\" validation rule failed for input: null"
      }
    ],
    "password": [
      {
        "rule": "minLength",
        "message": "\"minLength\" validation rule failed for input: '123'"
      }
    ]
  }
}
Garistar
  • 363
  • 3
  • 8