Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby to_json on objects wrapped in quote's

Tags:

json

ruby

I'm trying to create a super easy JSON webservice for a side-project. However I'm having some trouble converting my objects to JSON, could someone please help me out ?

I have the following classes:

class Location
  attr_reader :street, :city, :state, :country, :zip, :latitude, :longitude

  def initialize(street, city, state, country, zip, latitude, longitude)
    @street = street
    @city = city
    @state = state
    @country = country
    @zip = zip
    @latitude = latitude
    @longitude = longitude
  end

  def to_json
    {
      'street' => @street,
      'city' => @city,
      'state' => @state,
      'country' => @country,
      'zip' => @zip,
      'latitude' => Float(@latitude),
      'longitude' => Float(@longitude)
    }.to_json
  end
end

and

class Spot
  attr_reader :name, :category, :location, :id

  def initialize(id, name, category, location)
    @name = name
    @category = category
    @location = location
    @id = id
  end

  def to_json
    {
      'name' => @name,
      'category' => @category,
      'location' => @location.to_json,
      'id' => @id
    }.to_json
  end

end

Given a random input I would like the output to be something like this:

{
"name":"Wirelab",
"category":"Bier",
"location":
{
    "street":"Blaatstraat 12",
    "city":"Enschede",
    "state":"Overijssel",
    "country":"Nederland",
    "zip":"7542AB",
    "latitude": 31.21312,
    "longitude":41.1209
}
,
"id":"12"
}

However the ouput I'll get is this:

{
    "name":"Wirelab",
    "category":"Bier",
    "location":"
    {
        "street\":"Blaatstraat 12",
        "city\":\"Enschede\",
        \"state\":\"Overijssel\",
        \"country\":\"Nederland\",
        \"zip\":\"7542AB\",
        \"latitude\":31.21312,
        \"longitude\":41.1209
    }
    ",
    "id":"12"
}

Could someone please explain me how I can fix this ?

EDIT:

I'm using a Sintra webservice which looks something like this:

get '/spots' do  
       #json = spots.to_json
       spot =  Spot.new("12", "Wirelab", "Bier", Location.new("Blaatstraat 12", "Enschede", "Overijssel", "Nederland", "7542AB", "31.21312", "41.1209"))
       json = spot.to_json
       if callback
         content_type :js
         response = "#{callback}(#{json})" 
      else
         content_type :json
         response = json
       end
  response
end
like image 514
Gidogeek Avatar asked May 02 '11 09:05

Gidogeek


2 Answers

This should fix it:

class Location
  attr_reader :street, :city, :state, :country, :zip, :latitude, :longitude

  def initialize(street, city, state, country, zip, latitude, longitude)
    @street = street
    @city = city
    @state = state
    @country = country
    @zip = zip
    @latitude = latitude
    @longitude = longitude
  end

  def to_hash
    {
      'street' => @street,
      'city' => @city,
      'state' => @state,
      'country' => @country,
      'zip' => @zip,
      'latitude' => Float(@latitude),
      'longitude' => Float(@longitude)
    }
  end

  def to_json
    self.to_hash.to_json
  end
end

class Spot
  attr_reader :name, :category, :location, :id

  def initialize(id, name, category, location)
    @name = name
    @category = category
    @location = location
    @id = id
  end

  def to_hash
    {
      'name' => @name,
      'category' => @category,
      'location' => @location.to_hash,
      'id' => @id
    }
  end

  def to_json
    self.to_hash.to_json
  end
end

Your problem was that in your to_json in Spot you were using the json string for Location and encoding that into json. This causes a json string within the json string which is why there were lots of '\'s - used as escape characters.

like image 107
david4dev Avatar answered Oct 12 '22 09:10

david4dev


If you try this:

@object = {
"name":"Wirelab",
"category":"Bier",
"location":
{
    "street":"Blaatstraat 12",
    "city":"Enschede",
    "state":"Overijssel",
    "country":"Nederland",
    "zip":"7542AB",
    "latitude": 31.21312,
    "longitude":41.1209
}
,
"id":"12"
}

And do this in your view

raw(@object)

You should be alright :)

edit

#controller
@object = Model.all

view
raw(@object.to_json)

will also work...

like image 33
Daniël Zwijnenburg Avatar answered Oct 12 '22 08:10

Daniël Zwijnenburg