Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to know which attribute called the waterline validation rule?

I'm doing my own custom validations on certain fields, so that only certain values are accepted (depending on the field) and the rest rejected. I would like to write a "filter" function that checks what attribute called the validation and from there decide what words the attribute is allowed to use. So the model would look something like this:

module.exports = {

    types: {

        filter: function(attribute) {

            if (attribute === 'number') {
                switch(attribute.value) {

                    case 'one':
                        return true;

                    case 'two':
                        return true;

                    default:
                        return false;

                }
            } else if (attribute === 'color') {
                switch(attribute.value) {

                    case 'red':
                        return true;

                    case 'blue':
                        return true;

                    default:
                        return false;

                }
           }

        },


    },

    attributes: {

        number: {
            type: 'string',
            required: true,
            filter: true
        },

        color: {
            type: 'string',
            required: true,
            filter: true
        }
    }
};

Of course, in normal Sails.js behaviour, "attribute" would not be the attribute, but the value of the attribute. (And attribute.value was just an example, meaning, I want the attribute value in there).

So, I want attribute to be the actual attribute that called the validation rule. Is this possible with Sails? I mean, I could write a function for each field in the model, but it would be nice to have a function that fits them all (I have many of them).

Thanks.

like image 909
JamHam Avatar asked Mar 27 '15 22:03

JamHam


1 Answers

Ok so I will answer your question, but this may not be exactly what you want. An attribute can have an "enum" which is how we'd achieve your end goal:

attributes: {
  state: {
    type: 'string',
    enum: ['pending', 'approved', 'denied']
  }
}

But I will assume that this code is just a contrived example. Here's a way that I think would work.

    module.exports = {
      
        

        types: {

            filter: function(attribute) {

                if (attribute === 'number') {
                    switch(attribute.value) {

                        case 'one':
                            return true;

                        case 'two':
                            return true;

                        default:
                            this.validationErrors.push(attribute);
                            return false;

                    }
                } else if (attribute === 'color') {
                    switch(attribute.value) {

                        case 'red':
                            return true;

                        case 'blue':
                            return true;

                        default:
                            this.validationErrors.push(attribute);
                            return false;

                    }
               }

            },


        },

        attributes: {
            validationErrors:(function(){
              
              var errors = [];
              
              return {
                push:function(attr){
                  errors.push(attr);
                },
                get:function(){
                  return errors;
                }
              };
              
            })(),

            number: {
                type: 'string',
                required: true,
                filter: true
            },

            color: {
                type: 'string',
                required: true,
                filter: true
            }
        }
    };

Edit:Used an attribute method instead of an attribute

There are potentially a couple problems with this answer. I'm not sure how waterline handles "this" within these custom type functions. Is "this" bound to the model? Or the instance of the model we're creating? There's a lot of questions to be asked here but maybe this can give you some ideas and create a discussion.

like image 131
aclave1 Avatar answered Sep 22 '22 03:09

aclave1