Playlistr: Artists

Now we can get into the meat of the application!

Artists

This is a simple CRUD feature to enable us to create, read, update and delete an Artist in our application.

To build this feature we need the following:

  • A migrations script to create our Artists database schema
  • A bean to represent our Artist (Model)
  • An interface to list, add, update and delete our Artist (View)
  • A handler to orchestrate all the actions (Controller)

If you remember we created our migrations script for Artists in the Migrate Create and Migrate Up / Down sections.

Artist.cfc (Model)

To describe the Artist entity to our application we need an Artist.cfc to hold the definition. This will be placed in the models directory.

To be able to reference a column in Quick with a getMyColumnName() or setMyColumnName() you have to add a property to access it. The only exception to this is the id column which you don't have to define as it's provided by default.

component extends="quick.models.BaseEntity" {
	property name;
}
models/Artist.cfc

Artists.cfc (Controller)

Next let's create our handler Artists.cfc. This will be placed in the handlers directory. Like all ColdBox handlers it extends coldbox.system.EventHandler.

Action: index()

The first and default action function is index().

function index( event, rc, prc ) {
	var artists = getInstance( "Artist" )
		.orderby( "id" )
		.get();

	if( artists.len() == 0 ) {
		relocate( "artists.create" );
	}

	prc.artists = artists;
}
models/Artist.cfc

Hopefully the intent of this method is clear. We first try and get all the Artist entities and if there are none we need to bounce the visitor onto the create view. If there are some artists then we need to convert the collection into an array of Artist entities for the listing view to loop over.

Quick uses it's integration with WireBox to getInstance( "Artist" ) of the Artist entity definition. We can then method-chains the orderby( "id" ) and get() methods to retrieve the Artist entities, if there are any.

Action: create()

If there are no Artist entities found, we need to create an Artist with the create() action method.

function create( event, rc, prc ) {
	param rc.id = "";

	prc.name = "";

	prc.action = "Create";
	prc.formAction = "artists.createAction";

	event.setView( "artists/createUpdate" );
}
models/Artist.cfc

All we are doing here is populating a number of rc and prc variables used in the set artists/createUpdate.cfm view.

Action: createAction()

When the createUpdate form is submitted the createAction action method is called and the form POST variables are sent to the createAction action method in the rc structure.

function createAction( event, rc, prc ) {
	param rc.name = "";

	getInstance( "Artist" )
		.create( {
			name: rc.name
		} );

	relocate( "artists" );
}
models/Artist.cfc

Here the Artist name in the rc structure from the form POST is used to create the record. The primary key id value is provided by the database auto-increment.

Action: update()

When we come to update an Artist we need to call the update() action method to populate the artists/createUpdate.cfm view.

function update( event, rc, prc ) {
	param rc.id = "";

	var artist = getInstance( "Artist" )
		.findOrFail( rc.id );

	prc.name = artist.getName();

	prc.action = "Update";
	prc.formAction = "artists.updateAction";

	event.setView( "artists/createUpdate" );
}
models/Artist.cfc

Once again we use WireBox to get an instance of our Artist entity. This time we use findOrFail( rc.id ) to find our record and return a single Artist entity. The primary key, rc.id, will be passed into the method via the ?id=123 name / value pair in the URL. If for any reason the primary key value of rc.id is not found, Quick will throw an "EntityNotFound" exception which, in a full application, should be caught with a try/catch around the code.

Action: updateAction()

When updating an Artist the form action submits to artists.updateAction.

function updateAction( event, rc, prc ) {
	param rc.id = "";
	param rc.name = "";

	getInstance( "Artist" )
		.findOrFail( rc.id )
		.update( {
			name: rc.name
		} );

	relocate( "artists" );
}
models/Artist.cfc

As you can see, we can find and update our changed Artist all in one expression. The same advice concerning an entity not being found applies.

Action: delete()

Finally, the last thing we want to do is to delete a record from the database.

function delete( event, rc, prc ) {
	param rc.id = "";

	getInstance( "Artist" )
		.findOrFail( rc.id )
		.delete();

	relocate( "artists" );
}
models/Artist.cfc

All the previous notes apply. This time we just call the delete() method on the found Artist entity and then take the visitor back to the listing view.

Finally we need to build the listing and create / update views we've referenced. There should be no surprises here. The only Quick related feature is in the index.cfm listing view. We are passing an array of Artist entities into the view via the prc.artists variable created in the handler. We then loop over that array to get each Artist. When we have a single Artist we can use the get methods provided by Quick to access the values like artist.getName().

So now we have a simple but complete CRUD feature using Quick!