[coldbox-3.5.0] Validation framework & Inheritance

I am working on some updates to Hyrule and I noticed a problem that you will ultimately have in Coldbox. When you use the this scope to define your constraints you will NOT be able to take advantage of inheritance. Take this example, you have a user and an employee. An employee has all the characteristics of a user but also adds the salary property.

User.cfc

component accessors=“true” {

property String firstname;
property String lastname;
property String email;
property String username;
property String password;

this.constraints = {
firstname = {required=true,min=3},
lastname = {required=true,min=3},
email = {required=true,type=“email”},
username = {required=true,size=“6…15”},
password = {required=true}
};

public User function init(){
return this;
}

}

Employee.cfc

/**

  • @accessors true
  • @extends User
    */
    component {

property Numeric salary;

this.constraints = {
salary = {required=true}
};

public Employee function init(){
return this;
}

}

When you go to validate the Employee object the only property that will validate is the salary property. There will also be some issues serializing the object.

Luis - There is a way to solve this and I will ping you offline about this but I just wanted to make everyone aware of the issue. Also I haven’t been able to verify this just yet in Coldbox 3.5 yet but looking at the code I don’t believe it is being handled.

Yea you are overriding the entire structure. I would suggest not declaring the entire constraints struct but just adding or overriding.

This.constraints.salary = {};

There is actually a way around this using a hack I picked up from Elliot Sprehn. There is a way to attach meta data to a component. In my example I am including the metadata.cfm but I am sure in coldbox you could somehow automagically mix this in. This works for me I just don’t like having to manually include the metadata.cfm so I will try and find a way around that.

Employee.cfc

/**

  • @accessors true
  • @extends User
    */
    component {

property Numeric salary;

include “metadata.cfm”;
metadata.constraints = {
salary = {required=true}
};

public Employee function init(){
return this;
}

}

User.cfc

component accessors=“true” {

property String firstname;
property String lastname;
property String email;
property String username;
property String password;

include “metadata.cfm”
metadata.constraints = {
firstname = {required=true,min=3},
lastname = {required=true,min=3},
email = {required=true,type=“email”},
username = {required=true,size=“6…15”},
password = {required=true}
};

public User function init(){
return this;
}

}

metadata.cfc

// STATIC VARIABLES HACK metadata = getMetaData(this); if( !structKeyExists(metadata,"constraints") ){ lock name="StaticVariables(#metadata.name#)" timeout="10"{ if( !structKeyExists(metadata,"constraints") ){ metadata.constraints = [

];
}
}
}

I like your idea though just adding to the already existing this.constraints struct