Mura ORM Entity

In a nutshell, a Mura ORM entity is described by creating a ColdFusion component (.CFC). Mura leverages some of the standard attributes of a Mura ORM component, and also utilizes some custom attributes, as outlined in the table below.

Attribute Req/Opt Default Description
bundleable Optional true If false, entities will not be included in any bundles.
cachename Optional   You may optionally supply a custom cache name to use when being stored in Mura's cache factory.
datasource Optional m.globalConfig('datasource') If you wish to use a datasource that's different from the one Mura uses by default, you may supply one here.
dbtype Optional  

If specifying a datasource attribute, specify the database type. Valid options include:

  • mysql
  • mssql
  • oracle
  • postgres
discriminatorcolumn Optional empty string You may specify a property to filter on by default.
discriminatorvalue Optional empty string If using a discriminatorcolumn, you may specify the property's criteria to filter on by default.
extends Required mura.bean.beanORM This attribute should always be present, and should always extend mura.bean.beanORM or mura.bean.beanORMHistorical
entityname Required   This is the name of the object/entity.
manageschema Optional true If false, Mura will not manage the underlying table for the entity, and you are assuming all responsibility for any schema changes.
orderby Optional   You may pass a comma-delimited list of properties to sort by.
public Optional false If true, allows the entity to be used via the JSON API by non-administrative users. If false, users must be logged in, and have access to the specific site in order to work with the entity.
readonly Optional false If true, Mura will not allow any new records to be added to the database, or any updates to existing records in the database.
scaffold Optional false If true, allows the entity to be managed via the Mura ORM Scaffolder.
table Required   Specify the name to use for a database table to store data about this entity.
usetrash Optional true If false, entities will not be moved to the Trash Bin, and will be hard deleted instead.

Example Mura ORM Component

component 
  extends="mura.bean.beanORM"
  entityname="something"
  table="somethings"
  bundleable="true"
  displayname="SomethingBean"
  public=true
  orderby="{someproperty}" {

  // Properties & Methods

}

Mura ORM Component Properties

To describe the various properties/attributes and relationships of Mura ORM entities, use CFML properties. The following table describes the available attributes for Mura ORM component properties.

Attribute Req/Opt Default Description
cascade Optional   If the property is a related entity and the value is "delete", when the parent entity/object is deleted, any related entities will also be deleted.
cfc Optional   If the property is a related entity, set to the related entity's "entityname" value.
comparable Optional true If false, the property will not be included in entity comparisons. For example:
entityDifferences = entityA.compare(entityB);
datatype Optional varchar

Valid options are:

  • datetime
  • int
  • text
  • tinyint
  • smallint
  • varchar
  • char
  • number
  • boolean
  • float
  • double
  • blob
default Optional   If the required attribute is set to "no", or not specified, you may supply a default value to use.
fieldtype Optional  

If property is a primary key, you should set fieldtype to "id". Mura will then create a UUID for each new object stored in the database.

If property is a related entity, you may specify the relationship type here. The left side of the "to" types listed below is the parent entity, and the right side of the "to" is the related entity. So, for example "one-to-many" would mean one parent entity could have many related entities, and so on. Valid options are:

  • one-to-one
  • one-to-many
  • many-to-one
  • many-to-many
  • index  (sets a non-unique index on the column in the underlying database)
fkcolumn Optional  

If the property is a related entity, you may specify the attribute of the entity to store in this field. This is useful when creating relationships to Mura's entities. For example:

property name="site" 
         cfc="site" 
         fieldtype="many-to-one" 
         fkcolumn="siteid";
html Optional false

This property is parsed only if stricthtml=true in the settings.ini.cfm file. 

If true, Mura will allow HTML in the string to be saved. If false, Mura will return an error if the string contains HTML when being saved.

length Optional 50 If the datatype attribute is set to "varchar" or "char", you may specify the maximum number of characters to allow.
loadkey Optional   If the property is a related entity, you may specify the attribute of the entity to load by.
message Optional   If required, or fails validation, the error message to return to the user.
relatesto Optional   Alias for "cfc"
name Required   Name of the property.
nullable Optional false If true, empty values will be stored as NULL.
orderby Optional   If property is a related entity, you may specify the related entity's property you wish to sort by.
persistent Optional true If false, a column in the related table will not be created for the property.
required Optional false If true, an error will be sent to the user if a value is not set.
singluarname Optional  

If the property is a related entity, this allows you to use a singular name in lieu of the property name itself. For example:

property name="addresses" 
         singularname="address" 
         cfc="address" 
         fieldtype="one-to-many";
validate Optional  

If you desire the entity to be validated before saving, you may use one of the following options:

  • date
  • datetime
  • numeric
  • email
  • regex
  • url

Validation Attributes

If property has a "validate" attribute, you may include additional attributes to the property for validation.

Attribute Description
regex The regular expression to use for validation.
minvalue The minimum value to allow.
maxvalue The maximum value to allow.
minlength The minimum length to allow.
maxlenth The maximum length to allow.
inlist The list to compare against.
method A custom entity method to execute.
lte Less than or equal to.
lt Less than.
gte Greater than or equal to.
gt Greater than.
eq Equal to.
neq Not equal to.

The example below illustrates how to use a validation attribute, when a property has a "validate" attribute.

property name="year" datatype="int" validate="numeric" minvalue="1900" maxvalue="2017";

Related Entity Synthesized Methods

If the property is a related entity, and the fieldtype attribute is either "one-to-many" or "many-to-many", the following methods are automatically available to the entity itself. The methods below are executed for both the property's name and singularname.

Method Description
get{PropertyName}Iterator Returns an iterator of related entities. For example: entity.getAddressesIterator()
get{PropertyName} Under the hood, returns get{PropertyName}Iterator.
get{PropertyName}Query Returns a recordset/query of the related entities. For example: entity.getAddressesQuery()
has{PropertyName} Returns a recordcount of related entities. Useful for if/else statements.
add{PropertyName} Pass in the object/entity to save as a related entity, and Mura will automatically save the related entity when executing the call to entity.save(). Useful for adding multiple related entities. For example: entity.addPhoneNumber(phoneNumberObject)
remove{PropertyName} Pass in the object/entity to be deleted, and Mura will automatically delete the related entity when executing the call to entity.save(). For example: entity.removePhoneNumber(phoneNumberObject)

If the property is a related entity, and the fieldtype attribute is either "one-to-one" or "many-to-one", the following methods are automatically available to the entity itself.

Method Description
get{PropertyName} Returns the related entity. For example: entity.getEmergencyContact()
add{PropertyName} Pass in the object/entity to save as a related entity, and Mura will automatically save the related entity when executing the call to entity.save(). For example: entity.addEmergencyContact(emergencyContactObject)
remove{PropertyName} Pass in the object/entity to be deleted, and Mura will automatically delete the related entity when executing the call to entity.save(). For example: entity.removeEmergencyContact(emergencyContactObject)

Example Mura ORM Component With Properties

The following code defines an entity named "something" that contains a few basic properties.

component 
  extends="mura.bean.beanORM"
  entityname="something"
  table="somethings"
  bundleable="true"
  displayname="SomethingBean"
  public=true
  orderby="namefirst,namelast" {

  // primary key
    property name="somethingid" fieldtype="id";

  // attributes
    property name="namefirst" datatype="varchar" length="255" required=true;
    property name="namelast" datatype="varchar" length="255" required=true;

  // methods could go here
}

Working With Entities

The code examples below demonstrate various methods for working with entities. As you'll see, the syntax is no different than working with any other Mura bean object.

// Loading entities
entity = m.getBean('entityName')
          .loadBy(someAttribute='Something');

// Getting attributes
entity.get('attributeName');

// Setting attributes
entity.set('attributeName', 'Some Value')

// Deleting entities
entity.delete();

// Saving entities
entity.save();

// Get a feed of entites
m.getFeed('entityName');

Error Handling

As previously mentioned, working with entities is no different than working with any other Mura bean object. We've already covered a bit of error handling, but it doesn't hurt to review it once again here.

Errors are returned as a structure, where each key in the struct represents the object's attribute "name", and the value contains the error message itself.

entity.save();

// If the bean has errors, then it did not save...
if ( entity.hasErrors() ) {

  // errors are returned as a struct
  errors = entity.getErrors();

  WriteOutput('<h3>Please review the following errors:</h3><ul>');

  // Loop over the errors
  for ( e in errors ) {
    WriteOutput('<li>Attribute: #e# <br> Message: #errors[e]#</li>');
  }

  WriteOutput('</ul>');
} else {
  WriteOutput('<h2>Success :: No Errors!</h2>');
}

Custom Validation

Mura also allows you to include your own custom validation rules. In order to do so, you simply include a custom validate() method in your entity's component file (.CFC), and when a save() call is made on your entity, it will trigger your custom method. The key is you don't "return" anything, you simply add your custom errors to the existing errors struct.

You could also use this to do complex validation requirements. For example, maybe you have a custom radio button or checkbox, and when it's selected, your form displays additional form fields that you will then want to be "required". You could simply check for the existence and/or value of the triggering field, and if it exists, run through each of the additional required form fields in your own validation.

The example below demonstrates how to create your own error messages when validating an attribute of your entity.

public any function validate() {

  // This runs the standard validation ... 
  // which will use your property definition's "validate" requirements, etc.
  // and it also gives you a way to reference the entity object itself
  var obj = super.validate();

  // Obtain a reference to any errors
  var errors = obj.getErrors();

  // Now, you can check anything you want on your properties or entity attributes
  // For example, if you have a property labeled "wantsmoreoptions" and it's true,
  // You could check for the other fields
  if ( obj.get('wantsmoreoptions') ) {

    // Yes, they want more options!
    // Make sure they completed them ...
    if ( !Len(obj.get('option99')) ) {
      errors.option99 = 'Option 99 is required.';
    }    

    // etc. ...
  }

}