Adding json responses to all of your controller actions

written by Scott on January 14th, 2008 @ 10:39 AM

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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.

Comments are closed