-
Notifications
You must be signed in to change notification settings - Fork 6
Models
The model layer contains your application's business logic, typically inside persistent entities or service objects.
Models in a ColdMVC application serve two purposes: to represent individual records in your database through properties as well as to provide database access through an abstraction layer on top of Hibernate ORM.
To inject a singleton instance of a model into your components, simply add a property to your component with the name of model, prefixed with an underscore. For example, to inject a User model, just add property _User; to your component.
Models in ColdMVC contain several methods that help you easily query your database. Most of the methods are based on domain class methods found in Grails.
Note: some of the methods listed below can accept an options argument, which can be used for pagination and sorting.
var books = _Book.list({
sort = "title",
order = "asc",
max = "10",
offset = "20"
});
Returns the total number of records.
var count = _Book.count();
Returns the number of records with matching parameters. Uses dynamic finders via onMissingMethod().
var count = _Book.countByTitle("The Da Vinci Code");
Returns the number of records with matching parameters.
var count = _Book.countWhere({
title = "The Da Vinci Code"
});
Deletes a record from the database.
var book = _Book.get(id);
book.delete();
If called on a singleton model, checks to see if a record exists with a certain ID.
if (_Book.exists(12)) {
// the book with ID "12" exists in the database
}
If called on an instance of a model, checks to see if the model has already been stored in the database and has an ID.
var book = _Book.get(12);
if (book.exists()) {
// the book with ID "12" already exists in the database
}
Executes a query and returns either the first result or a new instance of a model if no results are found.
var book = _Book.find("from Book where book.title = :title", {
title = "The Da Vinci Code"
});
Executes a query and returns an array of records.
var books = _Book.findAll("from Book where book.title like :title", {
title = "The Da Vinci Code"
});
Returns an array of records with matching parameters. Uses dynamic finders via onMissingMethod().
var books = _Book.findAllByTitle("The Da Vinci Code");
Returns an array of records with matching parameters.
var books = _Book.findAllWhere({
title = "The Da Vinci Code"
});
Returns a record with matching parameters or a new instance of a model if no results are found. Uses dynamic finders via onMissingMethod().
var book = _Book.findByTitle("The Da Vinci Code");
Returns a record with matching parameters or a new instance of a model if no results are found.
var book = _Book.findWhere({
title = "The Da Vinci Code"
});
Returns a record with a matching ID or a new instance of a model if no results are found. Optionally allows you to populate the result.
var book = _Book.get(1, {
title = "The Da Vinci Code",
author = "Dan Brown"
});
Returns an array of records within a comma-separated list or array of IDs. The results within the array will be in the same order as the IDs that were passed in unless a sort option is specified.
var books = _Book.getAll("1,2,3");
var books = _Book.getAll([1,2,3]);
Returns an array of records.
var books = _Book.list({
sort = "title",
order = "asc"
});
Creates a new instance of a model. Optionally allows you to populate the result.
var book = _Book.new({
title = "The Da Vinci Code",
author = "Dan Brown"
});
Populates an instance of a model. Optionally specify a list of valid properties to populate.
var book = _Book.new();
book.populate({
title = "The Da Vinci Code",
author = "Dan Brown"
});
Provides a multi-purpose getter/setter for properties.
If a value is specified, the property is set to the value and the instance of the model is returned.
var book = _Book.new();
book.prop("title", "The Da Vinci Code"); // setter
If a value is not specified, the current value of the property is returned.
var book = _Book.get(12);
var title = book.prop("title"); // getter
Saves a record to the database.
var book = _Book.new({
title = "The Da Vinci Code",
author = "Dan Brown"
});
book.save();
Validates a model and returns a validation result.
var book = _Book.new({
title = "The Da Vinci Code",
author = "Dan Brown"
});
var result = book.validate();
if (result.isValid()) {
book.save();
}
ColdMVC has the following operators that can be used with the findBy(), findAllBy(), findWhere(), findAllWhere(), countBy(), countWhere(), and createQuery() methods on your models.
- equal
- notEqual
- like
- notLike
- in
- notIn
- startsWith
- notStartsWith
- endsWith
- notEndsWith
- isNull
- isNotNull
- greaterThan
- greaterThanEquals
- lessThan
- lessThanEquals
- before
- after
- onOrBefore
- onOrAfter
Examples:
_Book.findByTitleLike("Da Vinci Code");
_Book.findAllByTitleLike("Da Vinci Code");
_Book.countByTitleLike("Da Vinci Code");
_Book.findWhere({
title = [ "like", "Da Vinci Code" ]
});
_Book.findAllWhere({
title = [ "like", "Da Vinci Code" ]
});
_Book.countWhere({
title = [ "like", "Da Vinci Code" ]
});
In addition, the following operators are aliased when working with createQuery() for shorter method names.
- eq: equal
- neq: notEqual
- gt: greaterThan
- gte: greaterThanEquals
- lt: lessThan
- lte: lessThanEquals
Examples:
var q = _Book.createQuery();
q.where(
q.eq("author", "Dan Brown"),
q.like("title", "Da Vinci Code")
);
var books = q.list();
Most of the time you can use ColdMVC's basic ORM methods (get(), list(), findAllWhere(), etc...) for querying your database.
However, sometimes you need to build a complex query and using findAllWhere() won't get the job done.
When this situation occurs, you can use the find() or findAll() methods on your model and write raw HQL. While writing HQL is perfectly fine, it can sometimes lead to problems due to Hibernate's case-sensitivity and casting ColdFusion variables to Java data types.
A better option is to use ColdMVC's query builder using the createQuery() method on your models.
In addition to all of the standard ColdMVC operators, the following methods are available when building a query:
Appends clauses to a query concatenated by an and conjunction.
var q = _Team.createQuery();
q.innerJoin("city");
q.where(
q.and(
q.eq("team.name", "Twins"),
q.eq("city.name", "Minneapolis")
)
);
var teams = q.list();
Appends clauses to a query concatenated by an and conjunction.
var q = _Team.createQuery();
q.innerJoin("city");
q.where(
q.eq("team.name", "Twins")
);
q.andWhere(
q.eq("city.name", "Minneapolis")
);
var teams = q.list();
Executes the query and returns the number of results.
var q = _Team.createQuery();
var teams = q.count();
Executes the query and returns the first result or a new instance of the model if no results are found.
var q = _Team.createQuery();
q.innerJoin("city");
q.where(
q.eq("team.name", "Twins"),
q.eq("city.name", "Minneapolis")
);
var team = q.get();
Adds an inner join to the query.
var q = _Team.createQuery();
q.innerJoin("team.city");
q.where(
q.eq("city.name", "Minneapolis")
);
var teams = q.list();
Adds a join to the query.
var q = _Team.createQuery();
q.join("city");
q.where(
q.eq("city.name", "Minneapolis")
);
var teams = q.list();
Adds a left join to the query.
var q = _Team.createQuery();
q.leftJoin("team.city", "c");
q.where(
q.isNull("c.id");
);
var teams = q.list();
Executes the query and returns an array of results.
var q = _Team.createQuery();
var teams = q.list();
Specifies the maximum number of results for the query.
var q = _Team.createQuery();
q.max(10);
var teams = q.list();
Specifies the offset for the query.
var q = _Team.createQuery();
q.offset(20);
var teams = q.list();
Appends clauses to a query concatenated by an or disjunction.
var q = _Team.createQuery();
q.innerJoin("city");
q.where(
q.or(
q.eq("team.name", "Twins"),
q.eq("city.name", "Minneapolis")
)
);
var teams = q.list();
Specifies the order for the query.
var q = _Team.createQuery();
q.order("asc");
var teams = q.list();
Appends clauses to a query concatenated by an or disjunction.
var q = _Team.createQuery();
q.innerJoin("city");
q.where(
q.eq("team.name", "Twins")
);
q.orWhere(
q.eq("city.name", "Minneapolis")
);
var teams = q.list();
Specifies the select statement for the query. Can be used to execute custom select statements.
var q = _Team.createQuery();
q.select("select count(team.id)");
var teams = q.get();
Specifies the sort for the query.
var q = _Team.createQuery();
q.sort("name");
var teams = q.list();
Appends clauses to a query concatenated by an and conjunction.
var q = _Team.createQuery();
q.where(
q.eq("name", "Twins")
);
var teams = q.list();
You can access your model's properties several ways.
Option 1: You can use ColdFusion's built-in getters and setters for persistent properties.
var book = _Book.new();
book.setTitle("The Da Vinci Code"); // setter
var title = book.getTitle(); // getter
Option 2: You can use your model's prop method.
var book = _Book.new();
book.prop("title", "The Da Vinci Code"); // setter
var title = book.prop("title"); // getter
Option 3: You can access each property as a method via onMissingMethod().
var book = _Book.new();
book.title("The Da Vinci Code"); // setter
var title = book.title(); // getter
It can be easier to use either option 2 or 3 when working with relationships as ColdMVC will automatically cast empty values to NULL and handle building relationships for you.
For example, if each Book had a relationship to an Author, here is how you would update a Book with an ID of 2 to have an Author with an ID of 5 for each of the options listed above.
Option 1:
var book = _Book.get(2);
var author = _Author.get(5);
book.setAuthor(author);
Option 2:
var book = _Book.get(2);
book.prop("author", 5);
Option 3:
var book = _Book.get(2);
book.author(5);
As you can see, options 2 and 3 are considerably shorter than option 1.
Model helpers are custom functions that are available to your models that expose common model-related methods without having to extend a base model.
You can expose any function on a singleton bean or a helper as a model helper by adding an @modelHelper {name} annotation to the function.
- toJSON
- toQuery
- toString
- toStruct
- toXML
- validate