An MVC implementation for Appcelerator – Part 4: Model and DB

In part 3 we setup a simple app based on Fabio Barbieri‘s evolution of Appcelerator on Rails. Now is time to start playing with some models and data.

The application had two controllers: Products and Clients. We added to the Products controller a function that shows a static message when we click on the button. Now we want to fetch the data to display from the database.

First create the “Client” model:

ruby scripts/generate.rb model Client name:string
Resources/models/client.js
Resources/db/migrations/20110721190738.js

Resources/models/client.js

var Client = Model.extend({
    table_name: "clients",
    _fields: {id: Number, name : String},

    find: function(id) {
        var model = new Client(this.db, this._find(id));
        return model;
    },

    item_from: function(row) {
        var model = new Client(this.db, this._item_from(row));
        return model;
    }
});

Resources/db/migrations/20110721190738.js

migrate("20110721190738", "CREATE TABLE IF NOT EXISTS clients (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name STRING)");

Each time we start the application, the closure in db.js run the migrations not already executed. We can run the app to create the table then add some fake data with a SQLite manager. Alternatively we can create another migration to add sample data, it’s up to you.

Create Resources/db/migrations/20110721190739.js (one unit after previous migration) and write:

migrate("20110721190739", "INSERT INTO clients (name) VALUES ('John Doe')");
migrate("20110721190740", "INSERT INTO clients (name) VALUES ('Jane Doe')");

When you start the app this migration will insert into “clients” table two items.

Finally add a function to the Clients controller to load the data and display them on an alert box:

loadClients: function() {
	var c = new Client(db);
	var recs = c.find_all();
	var results = "Clients:n";
	if(recs.length > 0)
	{
		for(var i = 0; i < recs.length; i++)
		{
			results += recs[i].name + 'n';
		}
	}
	else
	{
		results += "none";
	}
	alert(results);
}

And the corresponding button into the Clients view:

var button = Titanium.UI.createButton({
	title:'Click me',
	font:{fontSize:12,fontWeight:'bold'},
	width:65,
	height:30,
	top:300
});
button.addEventListener('click', this.controller.loadClients);
this.win.add(button);

Launch the simulator and switch to the “Client” tab. When you click on the button the client list will be showed.

You can download the sample code and look use it for your projects.

With this fourth part we conclude this series of tutorials. It’s not too much, just a start but we are planning to create a new series of tutorials in september that will cover the coding of a complete application with Appcelerator on Rails.

Enjoy and have a good summer vacation!

Links:
Part 1: Introduction
Part 2: Improvements
Part 3: A simple demo

  • Vikas

    Great article. It shows the MVC concepts very nicely.

  • Vikas

    Actually, last comment was meant for your MVC stuff. I still have to go thru this Model n DB article.

    Thanks,
    Vikas

  • Morten

    Hi Andrea

    Great tut!

    I was wondering if you could extend the functionality to allow for multiple inserts?

    To reduce the number of I/O to the database, you could allow this:

    insert into foo (col1,col2,…coln) values (val1,val2,…valn),(val1,val2,…,valn),…

    • http://andreamostosi.name Andrea Mostosi

      Hi Morten, thank you for your comment.

      If you are talking about migration you already can do that. “migrate” function simply execute SQL code so you can write everything you want.

      If you are talking about the “active_db” structure instead, is a good idea don’t do that because it implements something similar to Ruby’s ActiveRecord. It enables you to map your object on the corresponding row on the DB so multiple insert aren’t usefull.

      Bye

  • tcd

    Any idea why this will not compile in titanium 1.7.5? Only works in 1.7.1 otherwise I get this error:

    2011-11-07 16:00:26.933 [95442:6803] -[TiFilesystemFileProxy characterAtIndex:]: unrecognized selector sent to instance 0x6d48b10
    2011-11-07 16:00:26.978 [95442:6803] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘-[TiFilesystemFileProxy characterAtIndex:]: unrecognized selector sent to instance 0x6d48b10′