Model Definition Overview
Overview
Basically the model in Qcadoo Framework defines the structure of the table in database and maps it into key-value structure.
Additionally it defines fields' contraints and custom methods, called hooks, which are linked with model lifecycle.
All models used by system are defined in separated XML files located under the directory src/main/resources/pluginIdentifier. They are registered in qcadoo-plugin.xml using model module.
Please find below a list of all build-in modules related to model.
-
Dictionary Module — dictionary - defines new dictionary.
-
Model Enum Value Module — model-enum-value - defines new value of the exising enum field.
-
Model Field Module — model-field - defines new field in existing model.
-
Model Hook Module — model-hook - defines new hook in existing model.
-
Model Module — model - defines new model (database table and its mapping).
Structure
Name of defined entity must be unique within the plugin scope.
Default value of attribute "auditable" is "false" and the attribute itself is not mandatory. When it's "true" every entity in the database defined by the model will have standard predefined fields: createdate, updatedate, createuser and updateuser. These fields store information about who and when created and last edited the entity.
<model name="sampleModel" auditable="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schema.qcadoo.org/model" xsi:schemaLocation="http://schema.qcadoo.org/model http://schema.qcadoo.org/model.xsd"> <fields> // FIELD DEFINITIONS </fields> <hooks> // HOOK DEFINITIONS </hooks> // IDENTIFIER </model>
Structure of field definition
<fieldType options />
or
<fieldType options> // VALIDATOR DEFINITIONS </fieldType>
Field types
- BelongsTo Field — belongsTo - many-to-one relation.
- Boolean field — boolean - true/false value.
- Date field — date - date.
- Datetime field — datetime - date with time.
- Decimal field — decimal - decimal number.
- Dictionary Field — dictionary - value from dictionary.
- Enum Field — enum - predefined value.
- HasMany Field — hasMany - one-to-many relation.
- Integer field — integer - integer number.
- ManyToMany Field — manyToMany - many-to-many relation.
- Password Field — password - password.
- Priority Field — priority - priority.
- String field — string - short text.
- Text field — text - long text.
- Tree Field — tree - tree-structured one-to-many relation.
Structure of validator definition
Validators are attached to fields.
<validatorType validatorOptions />
Validator types
Structure of hook definition
You can create custom event hook and attach it to defined model. To do it first you must create custom method (see this link).
<hookType hookOptions />
Hook types
- OnCopy Hook — onCopy - fired before copy.
- OnCreate Hook — onCreate - fired before create.
- OnDelete Hook — onDelete - fired before delete.
- OnSave Hook — onSave - fired before save.
- OnUpdate Hook — onUpdate - fired before update.
- OnView Hook — onView - fired during loading entity from database.
- ValidatesWith Hook — validatesWith - fired to validate entity or field.
Identifier
Role of entity identifier is to convert entity defined in model to a simple text (see expressions overview). It is used for example when showing operation messages. If "expression" is givet it is used to evaluate identifier, otherwise "number" field will be taken.
<identifier expression="#number + ' - ' + #name"/>
Examples
These examples definies three simple entities.
<?xml version="1.0" encoding="UTF-8"?> <model name="product" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schema.qcadoo.org/model" xsi:schemaLocation="http://schema.qcadoo.org/model http://schema.qcadoo.org/model.xsd"> <fields> <string name="number" required="true" unique="true"> <validatesLength max="40" /> </string> <string name="name" required="true" /> <enum name="typeOfMaterial" values="01component,02intermediate,03product,04waste" required="true" /> <string name="ean" /> <dictionary name="category" dictionary="categories" /> <dictionary name="unit" dictionary="units" required="true" /> <string name="batch"> <validatesLength max="255" /> </string> <string name="lastUsedBatch"> <validatesLength max="255" /> </string> <boolean name="genealogyBatchReq" /> <hasMany name="substitutes" model="substitute" joinField="product" cascade="delete" copyable="true" /> <hasMany name="technologies" model="technology" joinField="product" /> <hasMany name="orders" model="order" joinField="product" /> <hasMany name="operationProductInComponents" model="operationProductInComponent" joinField="product" /> <hasMany name="operationProductOutComponents" model="operationProductOutComponent" joinField="product" /> <hasMany name="substituteComponents" model="substituteComponent" joinField="product" /> </fields> <hooks /> <identifier expression="#number + ' - ' + #name"/> </model>
<?xml version="1.0" encoding="UTF-8"?> <model name="substitute" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schema.qcadoo.org/model" xsi:schemaLocation="http://schema.qcadoo.org/model http://schema.qcadoo.org/model.xsd"> <fields> <string name="number" required="true" unique="true"> <validatesLength max="40" /> </string> <string name="name" required="true" /> <belongsTo name="product" model="product" lazy="false" required="true" /> <hasMany name="components" model="substituteComponent" joinField="substitute" cascade="delete" copyable="true" /> <priority name="priority" scope="product" /> </fields> <hooks> <validatesWith class="com.qcadoo.mes.products.ProductService" method="checkIfProductIsNotRemoved" /> </hooks> <identifier expression="#number + ' - ' + #name" /> </model>
<?xml version="1.0" encoding="UTF-8"?> <model name="substituteComponent" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schema.qcadoo.org/model" xsi:schemaLocation="http://schema.qcadoo.org/model http://schema.qcadoo.org/model.xsd"> <fields> <belongsTo name="product" model="product" lookupField="name" required="true" /> <belongsTo name="substitute" model="substitute" required="true" /> <decimal name="quantity" required="true"> <validatesRange from="0" exclusively="true" /> <validatesPrecision max="7" /> <validatesScale max="3" /> </decimal> </fields> <hooks> <validatesWith class="com.qcadoo.mes.products.ProductService" method="checkIfSubstituteIsNotRemoved" /> <validatesWith class="com.qcadoo.mes.products.ProductService" method="checkSubstituteComponentUniqueness" /> </hooks> <identifier expression="#product['number'] + ' - ' + #product['name']"/> </model>