Our thin architecture with JavaScriptMVC / Rails

Architecture

The preceding image shows our architecture for every one of our applications. It illustrates how we use a double MVC architecture.

  • Using MVC with rails, we create REST services.
  • Using MVC with JavaScriptMVC we create the client application.

I’ll walk you through how we program for a simple use case. For this application, we have a person simply opening a page, and expecting to see a list of all tasks.

Before we begin, I would like to say we would typically have the list of tasks be sent with the page for performance reasons, but ignore that for now. I’m also going to use JMVC1.5 because it allows you to match the window load in every controller.  Here’s what happens:

1. The page loads (user action), we want to draw a list of todos. First we need to respond to the page load, we do that with a controller:

TodosController =  MVC.Controller.extend('todos',
{load: function(params) { ... code that gets called .. }
})

2. In our controller, we want to get a list of all tasks. So we use our Task model to do this. We give the find a callback, letting it know what to call when the request has completed.

load: function(){  Task.find('all', this.continue_to('list') )},
list: function(tasks){ ...}

3. We have to create a Model to wrap the task service. This is simple because we are using a REST service:

MVC.XMLRestModel.extend('tasks')

This allows us to do Task.find, which is basically sending a GET request to the url ‘tasks.xml’.4. This request gets handled by a Rails TodosController. The request gets routed to the TodosController’s index action which looks something like:

def index  @tasks = Task.find :all  respond_to do |format|   format.xml { render :xml => @tasks.to_xml }  endend

5. Of course, Rails uses its own Model which looks like:

class Task < ActiveRecord::Baseend

6. Similar to the JavaScriptMVC model, the Rails model converts Task.find to another service protocol. With JavaScriptMVC it was an HTTP / REST service. With Rails, it is SQL. The Model sends something like:

SELECT * FROM tasks;

7. The database sends the data back to the model.

8. The rails model converts the data into Task instances.

9. In this case, the controller just calls .to_xml on the instances to turn them into xml. If something more interesting was happening, the controller would process the Model returned data, and then pass it to a view before it is returned.

10. A view would take task data and convert it to XML.

11. The JavaScriptMVC Model takes the XML data and converts it to Task instances.

12. The JavaScriptMVC Controller list action gets called with a list of tasks and renders them in an element with ID=’tasks’ like this:

list: function(tasks){  this.tasks = tasks  this.render({to: 'tasks')}}

13. By default the list action uses an EJS view in views/tasks/list that looks something like:

<table>     <tr><th>name</th><th>date</th></tr>
<%for(var i=0; i<tasks.length; i++){ %>
     <tr>
        <td><%= tasks[i].name%></td>
        <td><%= tasks[i].date%></td>
     </tr>
     <%}%></table>

14. Finally, the rendered view is put in the page and presented to the user as a list of tasks.Latter I might put up why this architecture has so many advantages. It might seem complicated to setup. But this whole thing can be setup by code generators in rails and application generators/scaffolding in JavaScriptMVC2.0 in about 30 seconds.

Tags: ,

One Response to “Our thin architecture with JavaScriptMVC / Rails”

  1. Spencer Says:

    Where do you put the JavascriptMVC folder? In public/javascripts?

    … and btw, jabbify is hovering over the submit button.

Leave a Reply