Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
90 lines (73 sloc) 4.02 KB
Yesterday Ext <a href="http://extjs.com/blog/2009/06/03/ext-js-30-rc2-release-stable-robust-and-enhanced/">released</a> the second release candidate of Ext JS 3.0.
It included a new restful configuration option for the <a href="http://extjs.com/deploy/ext-3.0-rc2/docs/?class=Ext.data.Store">Ext.data.Store</a> and <a href="http://extjs.com/deploy/ext-3.0-rc2/examples/restful/restful.html">an example for its usage</a>.
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.
<h4>Here it is</h4>
<a href="http://github.com/steffen/extjswithrails.restful.sample/">http://github.com/steffen/extjswithrails.restful.sample/</a>
<h4>Here is what I did</h4>
On the frontend, I only changed the Proxy's URL from
<pre name="code" class="js:nocontrols">
var proxy = new Ext.data.HttpProxy({
url: 'app.php/users'
});
</pre>
to
<pre name="code" class="js:nocontrols">
var proxy = new Ext.data.HttpProxy({
url: '/users'
});
</pre>
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 <em>script/generate scaffold user
email:string first:string last:string</em> :))
<pre name="code" class="ruby:nocontrols">
class UsersController < users =" User.all" json =""> { :data => @users }
end
def create
@user = User.new(ActiveSupport::JSON.decode(params[:data]))
if @user.save
render :json => { :success => true, :message => "Created new User #{@user.id}", :data => @user }
else
render :json => { :message => "Failed to create user"}
end
end
def update
@user = User.find(params[:id])
if @user.update_attributes(ActiveSupport::JSON.decode(params[:data]))
render :json => { :success => true, :message => "Updated User #{@user.id}", :data => @user }
else
render :json => { :message => "Failed to update User"}
end
end
def destroy
@user = User.find(params[:id])
if @user.destroy
render :json => { :success => true, :message => "Destroyed User #{@user.id}" }
else
render :json => { :message => "Failed to destroy User" }
end
end
end
</pre>
Notice that the scaffold actions expects the data through the <em>user</em> parameter (params[:user]), but Ext's example is using <em>data</em> as root, that's why we have to use params[:data] here.
Check the <a href="http://github.com/steffen/extjswithrails.restful.sample/commits/master">commit log</a> for details regarding the steps it took me to create this example.
<h4>Here is how you can try it out</h4>
<ol>
<li>$ git clone git://github.com/steffen/extjswithrails.restful.sample.git</li>
<li>$ cd extjswithrails.restful.sample</li>
<li>Make sure you have ruby 1.8, rubygems, rails 2.3.2 and sqlite3-ruby installed.</li>
<li>$ rake db:migrate</li>
<li>$ script/server</li>
<li>Open http://localhost:3000/javascripts/ext/examples/restful-with-rails/restful.html in browser.</li>
</ol>
<h4>Here is what gave me a headache</h4>
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 <em>data</em>.
I think there should be two things fixed:
<ol>
<li>Send the whole data in JSON, such as <em>{ id: 1, data: { first: 'First', last: 'Last', email: 'Email' } }</em> and not as <em>id=1&amp;data={ first: 'First', last: 'Last', email: 'Email' }</em>.
The current workaround is to use <em>ActiveSupport::JSON.decode</em>
for the <em>data</em> parameter, since Rails can't automatically decode the parameters because the request isn't completely in JSON.</li>
<li>Send the AJAX request with the request header <em>'Content-Type': application/json</em>. 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 <em>Ext.Ajax.defaultHeaders = { 'Content-Type': 'application/json' }</em></li>
</ol>
<h4>Conclusion</h4>
The restful option rocks! :)