Skip to content

Instantly share code, notes, and snippets.

@johnnncodes
Created January 15, 2014 13:54
Show Gist options
  • Save johnnncodes/8436644 to your computer and use it in GitHub Desktop.
Save johnnncodes/8436644 to your computer and use it in GitHub Desktop.
Using custom validation messages in Sails.js. Credits to: sfb_
/**
* Takes a Sails Model object (e.g. User) and a ValidationError object and translates it into a friendly
* object for sending via JSON to client-side frameworks.
*
* To use add a new object on your model describing what validation errors should be translated:
*
* module.exports = {
* attributes: {
* name: {
* type: 'string',
* required: true
* }
* },
*
* validation_messages: {
* name: {
* required: 'you have to specify a name or else'
* }
* }
* };
*
* Then in your controller you could write something like this:
*
* var validator = require('sails-validator-tool');
*
* Mymodel.create(options).done(function(error, mymodel) {
* if(error) {
* if(error.ValidationError) {
* error_object = validator(Mymodel, error.Validation);
* res.send({result: false, errors: error_object});
* }
* }
* });
*
* @param model {Object} An instance of a Sails.JS model object.
* @param validationErrors {Object} A standard Sails.JS validation object.
*
* @returns {Object} An object with friendly validation error conversions.
*/
module.exports = function(model, validationError) {
var validation_response = {};
var messages = model.validation_messages;
validation_fields = Object.keys(messages);
validation_fields.forEach(function(validation_field) {
if(validationError[validation_field]) {
var processField = validationError[validation_field];
//console.log(processField);
processField.forEach(function(rule) {
if(messages[validation_field][rule.rule]) {
if(!(validation_response[validation_field] instanceof Array)) {
validation_response[validation_field] = new Array();
}
var newMessage={};
newMessage[rule.rule] = messages[validation_field][rule.rule];
validation_response[validation_field].push(newMessage);
}
});
}
});
return validation_response;
};
@meepeek
Copy link

meepeek commented Apr 6, 2014

I would like to know how to use this code as well.

@JrSchild
Copy link

JrSchild commented Apr 9, 2014

I would put this in a service e.g. services/transformValidation.js. That way you don't have to require() it and should be enough to do something like transformValidation(mymodel, error.Validation);

@kai23
Copy link

kai23 commented Jul 18, 2014

Clearly yes, you should create a service in api/services, for exemple HandleValidation.js

exports.transformValidation = function(model, validationError) {
    var validation_response = {};
    var messages = model.validation_messages;
    validation_fields = Object.keys(messages);

    validation_fields.forEach(function(validation_field) {

        if (validationError[validation_field]) {
            var processField = validationError[validation_field];
            processField.forEach(function(rule) {
                if (messages[validation_field][rule.rule]) {
                    if (!(validation_response[validation_field] instanceof Array)) {
                        validation_response[validation_field] = new Array();
                    }
                    var newMessage = {};
                    newMessage[rule.rule] = messages[validation_field][rule.rule];
                    validation_response[validation_field].push(newMessage);
                }
            });

        }
    });

    return validation_response;
};

And then, in your controller, after the « create »

if(err){
    if (err.ValidationError) {
        errors = HandleValidation.transformValidation(User, err.ValidationError);
        console.log(errors);
        res.json({
            success:false,
            errors: errors
        })
    };
}

And if you want to edit all validations rules at one place, you can edit it in the config/models.js

/**
 * Default model configuration
 * (sails.config.models)
 *
 * Unless you override them, the following properties will be included
 * in each of your models.
 */

module.exports.models = {

    // Your app's default connection.
    // i.e. the name of one of your app's connections (see `config/connections.js`)
    //
    // (defaults to localDiskDb)
    connection: 'mysql',


    validation_messages: {
        email: {
            required: 'Merci de fournir un email',
            unique: 'Cet email est déjà utilisé',
            email: 'Merci de fournir un email correct'
        }
    }
};

@derekbasch
Copy link

Thanks @kai23. That was very helpful.

@jgod
Copy link

jgod commented Sep 7, 2014

Elegant, thanks guys

@gadelkareem
Copy link

@lykmapipo
Copy link

For sails v0.11.X you may use this sails-hook-validation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment