The journal of Paul M. Watson.

Friday, March 03, 2006

JSON + Ajax + Ruby on Rails

While I would love to be using E4X, it isn't viable yet. So JSON it is. Here is how I got a simple JSON example working with Ruby on Rails over Ajax[1].

I'll assume you have a Rails project up and running with at least one model, controller, views etc.

First you want to install the JSON gem; gem install ruby-json

Then go into your model's code and put in the following require; require 'json/objects'. While still in the model add a to_json method with the following code:
result = Hash.new
self.class.content_columns.each do |column|
result[column.name.to_sym] = self.send(column.name)
end

result.to_json


Now off to the controller file you go. For this daft example I create the following method:
def jsonbit
@link = Link.find(params[:id])
@headers["Content-Type"] = "text/plain; charset=utf-8"
render_text @link.to_json
end


Then in your view you want to use prototype to fire off an Ajax call e.g. <%= remote_function(:complete => "var x = eval('(' + request.responseText + ')'); alert(x.title);", :url => { :action => :jsonbit, :id => link.id }) %>

So in that what we do is fire off a call to the jsonbit method with a model id and it returns JSON which is evaluated by JavaScript and one of the properties is alerted out.

Naturally you can return a collection of data and then loop through it using JavaScript too.

[1] Technically it should be Ajaj (Asynchronous JavaScript and JSON.) But really, nobody cares. So Ajax it is.

4 Comments:

Blogger Gizmo said...

I was a javascript/DHTML or as today called AJAX a very long time and I found another way to work around the cancer factor as I call it (javascript development). I call it WebGui and it is my new development environment it is basically WinForms like API combined with a AJAX unique communication layer making it possible to create complex applications like "Outlook Web Access" as simple as creating a WinForms application...

See my webcast here http://www.webgui-platform.com/Portals/0/Downloads/WebGui.Net.Videos.Explorer.Eng.avi

8:37 AM

 
Anonymous Farrel Lifson said...

If content_columns includes Enumerable (which it should if it responds to each) then you shoul be able to refactor this:

result = Hash.new
self.class.content_columns.each do |column|
result[column.name.to_sym] = self.send(column.name)
end
result.to_json

to

(self.class.content_columns.inject({}) do |result,column|
result[column.name.to_sym] = self.send(column.name)
result
end).to_json

Excuse the ugly formatting but this commenct box doesn't accept the 'pre' tag.

12:42 AM

 
Anonymous Myles Eftos said...

Thanks for that, I wish I had found you article three hours earlier :)

9:16 AM

 
Blogger Viking said...

You also should be able to refactor this:
(self.class.content_columns.inject({}) do |result,column|
result[column.name.to_sym] = self.send(column.name)
result
end).to_json
to:
(self.class.content_columns.inject({}) do |result,column|
result.merge(column.name.to_sym => self.send(column.name))
end).to_json

12:03 PM

 

Post a Comment

Links to this post:

Create a Link

<< Home