Mike Bailey

JSON with Ruby and Rails

| Comments

JSON is a beautiful format for storing objects as human readable text. It’s succeeded where XML has failed. Not only is it not shit, it’s actually quite good! But don’t just take my word for it, have a look at some of the “cool” ways you can generate and consume JSON.

Ruby support for JSON

Ruby’s JSON library makes parsing and generating JSON simple.

Converting between hash and json in Ruby linenos:false
1
2
3
4
5
6
7
$ irb
>> require 'json'
=> true
>> json_text = { :name => 'Mike', :age => 70 }.to_json
=> "{\"name\":\"Mike\",\"age\":70}"
>> JSON.parse(json_text)
=> {"name"=>"Mike", "age"=>70}

HTTParty helps with communicating with RESTful services

Here we grab a record from Facebook.

Retrieve a JSON Resource linenos:false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ irb
>> require 'awesome_print'
=> true
>> require 'json'
=> true
>> require 'httparty'
=> true
>> ap JSON.parse HTTParty.get('https://graph.facebook.com/Stoptheclock').response.body
{
                  "about" => "Abolish the 28 Day Rule for Victorian Shelters\n\nhttp://stoptheclock.com.au\n\ninfo@stoptheclock.com.au",
               "category" => "Community",
                "founded" => "2010",
           "is_published" => true,
                "mission" => "To bring an end to the law requiring Victorian shelters to kill healthy adoptable cats and dogs after four weeks.",
    "talking_about_count" => 3,
               "username" => "Stoptheclock",
                "website" => "http://stoptheclock.com.au",
        "were_here_count" => 0,
                     "id" => "167163086642552",
                   "name" => "Stop The Clock",
                   "link" => "http://www.facebook.com/Stoptheclock",
                  "likes" => 5517
}
=> nil

HTTParty gets Classy

Creating a simple class allows you to DRY things up a bit linenos:false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ irb
>> require 'httparty'
=> true
>> class Facebook
>>   include HTTParty
>>   base_uri 'https://graph.facebook.com/'
>>   # default_params :output => 'json'
?>   format :json
>>
?>   def self.object(id)
>>     get "/#{id}"
>>   end
>> end
=> nil
>>
>> require 'awesome_print'
>> ap Facebook.object('Stoptheclock').parsed_response
{
                  "about" => "Abolish the 28 Day Rule for Victorian Shelters\n\nhttp://stoptheclock.com.au\n\ninfo@stoptheclock.com.au",
               "category" => "Community",
                "founded" => "2010",
           "is_published" => true,
                "mission" => "To bring an end to the law requiring Victorian shelters to kill healthy adoptable cats and dogs after four weeks.",
    "talking_about_count" => 3,
               "username" => "Stoptheclock",
                "website" => "http://stoptheclock.com.au",
        "were_here_count" => 0,
                     "id" => "167163086642552",
                   "name" => "Stop The Clock",
                   "link" => "http://www.facebook.com/Stoptheclock",
                  "likes" => 5517
}
=> nil

Rails support for JSON

ActiveSupport::JSON knows how to convert ActiveRecord objects (and more) to JSON. Simone Carletti explains how this differs from the standard lib.

linenos:false
1
2
3
4
5
6
## Encode
json = ActiveSupport::JSON.encode(object) # extra methods like :include
json = Offering.first.to_json(:include => :outlet, :methods => [:days_waiting])

## Decode
ActiveSupport::JSON.decode(json)

Rails3 niceness

Adding JSON to your Rails3 app doesn’t require a lot of extra code. You can specify method calls and associated objects to include as well as restrict the attributes returned. Simple eh?

linenos:false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class PostController < ApplicationController
  respond_to :json, :html, :jpg, :xml

  def index
    respond_with(@posts = Post.all),
                   :methods => [:average_rating],
                   :include => :comments
  end

  def show
    respond_with(@post = Post.find(params[:id])), :only => [:name, :body]
  end

end

Posts in this series

Comments