Rendering JSON from a view

Hi,

I’m rendering a reasonable amount of JSON back to an application at the moment and the controllers are starting to get very messy with the code to structure and return the JSON. Is it possible to have a template that can handle the structuring of the JSON data and allow the controller to deal only with the business logic?

I’d envisage a controller like this:

class PersonController < ApplicationController def search @search = Person.search(params[:query]) end end

And a view named “person/search.json.erb” like:

json[:total] = @search.size json[:people] = @search.map do |person| { :first_name => person.first_name, :last_name => person.last_name } end

The json accessor used in the view would just be a hash that has to_json called on it and is sent back to the browser as the json string.

Is it possible to do this at the moment or do I need to add a template type to ActionView?

Cheers, -Jonathan,

Why do you not just use Rails to_json method?

class PersonController < ApplicationController   def search     @search = Person.search(params[:query])     render :json => @search.to_json   end end

Check out Rendering JSON in api.rubyonrails.org, just look into the render method. I'm not aware of a rxml version for json, but also can't really see a need for one either. to_json will convert your object directly into a javascript object so you can then eval them in your AJAX response.

I have been using to_json but the issue is that there is often a reasonable amount of processing to structure the json correctly, say 10 lines or so, and the controller is becoming messy. If it was a simple to_json call I wouldn’t be bothered.

I would also like access to the helpers for generating bits of HTML that need to be returned.

You’re right, what I’m after is rxml for JSON.

-Jonathan.

Well I knocked together an rjson view template. Here is the code for anyone who is interested:

class JsonTemplate def initialize(view) @view = view end

def render(template, local_assigns = nil)

@view.instance_eval do
  evaluate_assigns
 
  def json; @json ||= {}; end
 
  eval(template)
end

@view.json.to_json

end end

ActionView::Base.register_template_handler (‘rjson’, JsonTemplate)

-Jonathan.