ColdBox Basic – Models


The model layer represents the data structures and business logic, and is usually modeled by ColdFusion components. All ColdBox model objects are found under the model folder of the application root by convention. For security, place the models outside of the web root and use a ColdFusion Mapping to access them.

To learn more about ColdFusion Object Relational Mapping (ORM) and ColdBox model, visit these pages:

For this article we will be using ColdFusion ORM and the Virtual Service Layer approach to create a simple model that models a client object.

Environment

  • ColdFusion 10
  • ColdBox 3.8
  • Windows OS
  • MS SQL Server 2008

Preparation

If this is your first time learning ColdBox and you haven’t install it, read the following blog articles before proceeding:

OK, if you have ColdBox installed, then let’s browse to the model folder and create a new folder, and name it clients. Inside this new clients folder, create the following files:

  • Client.cfc
  • ClientService.cfc

coldbox-models-5

Create the appRoot Mapping

Here’s what you need to do to create the mapping (if it doesn’t exists – you can call it whatever you want):

  • Edit Application.cfc (the one at the coldbox application root level)
  • Add the following mapping (after the line COLDBOX_APP_KEY):
    this.mappings[‘/appRoot‘] = COLDBOX_APP_ROOT_PATH;

coldbox-models-6

Ensure ORM is Enabled

Firstly, in Application.cfc, add the following after the mappings (if it doesn’t exists – skip if exists, but ensure dbcreate is set to update):


this.ormEnabled = true;
this.datasource = "<your datasource name here>";
this.ormSettings = {
  dbcreate = "update",
  eventhandling = true,
  flushAtRequestEnd = false,
  cfclocation = []
};

Please note that your data source must already exists in the ColdFusion Admin. Secondly, in the onRequestStart function in the same file, add it if it’s not already there (so that you can reload the application’s ORM):


if( structKeyExists(URL,"ORMReload") ){
  ORMReload();
}

Create the Base Entity

We would like to strip out all the common properties of a model and place them inside this base entity. Then in each model that we create, we will inherit this base entity so that we keep the model as DRY as possible. To start off, create a new file called BaseEntity.cfc and save it into the model folder.

coldbox-models-4

Here’s a simple component for the base entity (you can add, modify or remove properties and methods to suit your purposes, or create your own from scratch):


component mappedsuperclass="true" {
   property name="dateCreated" ormtype="timestamp";
   property name="createdBy" sqltype="nvarchar" length="205";
   property name="lastUpdated" ormtype="timestamp";
   property name="lastUpdatedBy" sqltype="nvarchar" length="205";

   public any function init(){
        return this;
    }

   // EVENT HANDLERS
   public void function preInsert(){
       setDateCreated(now());        
   }
   public void function preUpdate(){
       setLastUpdated(now());        
   }   

   /** add common entity (model) methods and attributes of your choice in here **/
}

Create the model

Let’s create the model by editing Client.cfc and adding the following:


component persistent="true" extends="appRoot.model.BaseEntity" table="clients" {
   property name="client_id" fieldtype="id" generator="identity" setter="false";
   property name="firstname" sqltype="nvarchar" length="100";
   property name="lastname" sqltype="nvarchar" length="100";
   property name="dob" ormtype="date";
   
   //validations
   this.constraints = {
      firstname = {required=true, requiredMessage="First Name is required"},
      lastname = {required=true, requiredMessage="Last Name is required"},
      dob = {
         required=true, requiredMessage="DOB is required",
         type="date", typeMessage="DOB must be a valid date",
         discrete="lte:#now()#", discreteMessage="DOB cannot be in the future"
      } //dob
   } //constraints

   public Client function init(){
      //constructor
      return this;
   } //init

} //clients

Quick Tips

  • To inherit properties and method from another component, use its extends attribute, i.e. extends=”appRoot.model.BaseEntity”
  • In the example above, we are inheriting properties and functions from the base entity (i.e. BaseEntity.cfc)
  • When specifying the property type, you can either use ormtype or your database type
  • There are many different generators for the id field type. Select the one that is most suitable.
  • Make use of model constraints for simple server side model validations
  • To customise the constraint error message, use this convention:
    <constraintName>Message = “your custom error message”, e.g.
    requiredMessage=”First Name is required.”

Create the Service

Edit ClientService.cfc and add the following code snippet:


component extends="coldbox.system.orm.hibernate.VirtualEntityService" singleton {
   public ClientService function init(){
      super.init(entityName="Client");
      return this;
   }
}

Let’s Update the ORM

Browse to your application’s main page and do the following:

  • Update the ORM
    /index.cfm?ormReload
  • Refresh the application
    /index.cfm?fwreinit=1

Here are the existing tables after the initial install and implementation of the Solitary security module:

coldbox-models-1

After the application’s ORM is reloaded, the new client model is created, and hence this is what you will see in the database:

coldbox-models-2

That’s it! You’ve just created a model in ColdBox and its corresponding table and columns in your database. Continue learning!

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s