开发者

Ruby to_json on objects wrapped in quote's

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 =开发者_StackOverflow社区 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


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.


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...


I believe your problem is that to_json method in your Location class already returns a string:

def to_json
    {
      'street' => @street,
      'city' => @city,
      'state' => @state,
      'country' => @country,
      'zip' => @zip,
      'latitude' => Float(@latitude),
      'longitude' => Float(@longitude)
    }.to_json  # Here, this makes it to return a string
  end
end

And later, in your Spot class, your @location is evaluted as a string


If you using inspect or getting the output from irb, ie:

irb> object.to_json

Try using puts

irb> object.to_json.puts

then those slashes should disappear.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜