Skip to content
tonynelson19 edited this page Feb 19, 2013 · 2 revisions

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.

ORM

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"
});

count

Returns the total number of records.

var count = _Book.count();

countBy

Returns the number of records with matching parameters. Uses dynamic finders via onMissingMethod().

var count = _Book.countByTitle("The Da Vinci Code");

countWhere

Returns the number of records with matching parameters.

var count = _Book.countWhere({
	title = "The Da Vinci Code"
});

delete

Deletes a record from the database.

var book = _Book.get(id);

book.delete();

exists

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
}

find

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"
});

findAll

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"
});

findAllBy

Returns an array of records with matching parameters. Uses dynamic finders via onMissingMethod().

var books = _Book.findAllByTitle("The Da Vinci Code");

findAllWhere

Returns an array of records with matching parameters.

var books = _Book.findAllWhere({
	title = "The Da Vinci Code"
});

findBy

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");

findWhere

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"
});

get

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"
});

getAll

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]);

list

Returns an array of records.

var books = _Book.list({
	sort = "title",
	order = "asc"
});

new

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"
});

populate

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"
});

prop

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

save

Saves a record to the database.

var book = _Book.new({
	title = "The Da Vinci Code",
	author = "Dan Brown"
});

book.save();

validate

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();
}

Operators

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();

Queries

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:

and

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();

andWhere

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();

count

Executes the query and returns the number of results.

var q = _Team.createQuery();

var teams = q.count();

get

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();

innerJoin

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();

join

Adds a join to the query.

var q = _Team.createQuery();

q.join("city");

q.where(
	q.eq("city.name", "Minneapolis")
);

var teams = q.list();

leftJoin

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();

list

Executes the query and returns an array of results.

var q = _Team.createQuery();

var teams = q.list();

max

Specifies the maximum number of results for the query.

var q = _Team.createQuery();

q.max(10);

var teams = q.list();

offset

Specifies the offset for the query.

var q = _Team.createQuery();

q.offset(20);

var teams = q.list();

or

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();

order

Specifies the order for the query.

var q = _Team.createQuery();

q.order("asc");

var teams = q.list();

orWhere

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();

select

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();

sort

Specifies the sort for the query.

var q = _Team.createQuery();

q.sort("name");

var teams = q.list();

where

Appends clauses to a query concatenated by an and conjunction.

var q = _Team.createQuery();

q.where(
	q.eq("name", "Twins")
);

var teams = q.list();

Getters and Setters

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

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.

Standard Model Helpers

  • toJSON
  • toQuery
  • toString
  • toStruct
  • toXML
  • validate

Clone this wiki locally