Adding json responses to all of your controller actions
published 2008-01-14
Gerald has decided to use JSON responses for the mobile phone app we'll be building at the intermediate Rails workshop. I'm a lazy guy by nature, so there was no way I was going to paste in
format.json { render :json => @bookmark }
in to very controller method.
Now, the easiest way to do this would be to add JSON response to the
scaffolding. The templates are in
RAILS_ROOT/vendor/rails/lib/rails_generator/generators/components/scaffold/.
Open up the controller.rb template and add in the JSON response shown
above to the index, show, update and destroy methods and you're done.
Unfortunately, I had already mostly developed the API when I realized
that I had to add in the JSON responses (It's not Gerald's fault, he
told me long ago). So, I decided to write a quick rake task to do the
job for me. To use it, create a file called add_json.rake in
RAILS_ROOT/lib/tasks and copy the following code in to it:
namespace :rails do desc "Adds a 'format.json ...' line for each 'format.xml ...' line in every controller" task :add_json => :get_controller_list do @controllers.each do |controller| new_lines = File.open(controller, 'r').readlines.collect do |line| if line =~ /^\s+format\.xml/ [line, line.gsub(/xml/, 'json')] else line end end.flatten file = File.open(controller, 'w') do |file| file.puts new_lines end end end task :get_controller_list => :environment do @controllers = Dir.glob(File.join(RAILS_ROOT, 'app', 'controllers', '*_controller.rb')) end end
Call the task from RAILS_ROOT like this:
rake rails:add_json
The task opens up every controller, and every time it finds a line that
starts with format.xml, it makes a copy of that line just below with
every instance of 'xml' replaced with 'json'. It's ~~pretty~~ very
brain-dead: it doesn't check if the json response is already there, so
don't run it twice on the same project.