Thursday, June 4, 2009

RESTful store example with Rails

Yesterday Ext released the second release candidate of Ext JS 3.0.
It included a new restful configuration option for the and an example for its usage.

Update April 9, 2010: It's now compatible with the latest Ext JS 3.2.0 version.

Impressed by Ext's Chris Scott's lightweight Rails-like PHP MVC framework, I still wanted to get a feeling for this new feature by writing a Rails backend for this example.

Here it is

Here is what I did

On the frontend, I only changed the Proxy's URL from

var proxy = new{
url: 'app.php/users'


var proxy = new{
url: '/users'

Update April 9, 2010: Also added the "encode: false" config option to the JsonWriter and changed the root option from 'data' to 'users'. The latter is just for making the example a little more clearer.

On the backend side, I created the User model, added the model to the routes.rb file, and created the following users controller:
(I didn't do all by hand, thanks to script/generate scaffold user
email:string first:string last:string

class UsersController < ApplicationController

def index
@users = User.all

render :json => { :users => @users }

def create
@user =[:users])

render :json => { :success => true, :message => "Created new User #{}", :users => @user }
render :json => { :message => "Failed to create user"}

def update
@user = User.find(params[:id])

if @user.update_attributes(params[:users])
render :json => { :success => true, :message => "Updated User #{}", :users => @user }
render :json => { :message => "Failed to update User"}

def destroy
@user = User.find(params[:id])

if @user.destroy
render :json => { :success => true, :message => "Destroyed User #{}" }
render :json => { :message => "Failed to destroy User" }


Notice that the scaffold actions expects the data through the user parameter (params[:user]), but Ext's example is using data as root, that's why we have to use params[:data] here.

Check the commit log for details regarding the steps it took me to create this example.

Here is how you can try it out

  1. $ git clone git://

  2. $ cd extjswithrails.restful.sample

  3. Make sure you have ruby 1.8, rubygems, rails 2.3.2 and sqlite3-ruby installed.

  4. $ rake db:migrate

  5. $ script/server

  6. Open http://localhost:3000/ in browser.

Update April 9, 2010: The headaches were fixed with later versions.

Here is what gave me a headache

Unfortunately, Ext JS isn't sending the whole data in JSON, but rather as normal POST parameters with one parameter that carries the JSON string. That parameter's name is taken from the root option from your reader, in our example its data.

I think there should be two things fixed:

  1. Send the whole data in JSON, such as { id: 1, data: { first: 'First', last: 'Last', email: 'Email' } } and not as id=1&data={ first: 'First', last: 'Last', email: 'Email' }.

    The current workaround is to use ActiveSupport::JSON.decode
    for the data parameter, since Rails can't automatically decode the parameters because the request isn't completely in JSON.

  2. Send the AJAX request with the request header 'Content-Type': application/json. This way, if the request would completely be in JSON, Rails could figure out that it receives JSON data.

    A workaround would be to add Ext.Ajax.defaultHeaders = { 'Content-Type': 'application/json' }

Here is my conclusion for today

I like the restful option, but dislike Ext's AJAX code (not the new stuff, I mean the one that's in the Connection class and ext-base file),'s BR tags all over the place, blogger not allowing to change post's URLs, and MarsEdit enabling comments with every save and messing up my third party commenting system. :-)
blog comments powered by Disqus