HTTParty - 强类型对象的JSON

时间:2012-02-09 21:21:19

标签: ruby httparty

是否可以让HTTParty将结果从GET反序列化为强类型的ruby对象?例如

class Myclass
 include HTTParty

end

x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')

puts x.total
puts x.questions[0].title

现在它将其反序列化为哈希

puts x["total"]

我的问题实际上是,如果HTTParty支持这个OTB,而不是安装额外的宝石。

修改

我还是Ruby的新手,但我记得类字段都是私有的,因此需要通过getter / setter方法访问它们。那么这个问题可能不是一个有效的问题吗?

2 个答案:

答案 0 :(得分:2)

如果您只是想要方法语法,可以使用开放结构。

require 'httparty'
require 'ostruct'

result = HTTParty.get 'http://api.stackoverflow.com/1.0/questions?tags=HTTParty'
object = OpenStruct.new result
object.total # => 2634237

一个可能的缺点是这个对象是完全开放的,如果你在它上面调用一个不存在的方法,它将只返回nil(如果你调用一个setter,它将创建setter和getter)

答案 1 :(得分:1)

听起来您希望Myclass::get的返回值是Myclass的实例。如果是这种情况,您可以从HTTP请求缓存返回值并实现method_missing以从该哈希返回值:

class Myclass
  include HTTParty

  attr_accessor :retrieved_values

  def method_missing(method, *args, &block)
    if retrieved_values.key?(method)
      retrieved_values[method]
    else
      super
    end
  end

  def self.get_with_massaging(url)
    new.tap do |instance|
      instance.retrieved_values = get_without_massaging(url)
    end
  end

  class << self
    alias_method :get_without_massaging, :get
    alias_method :get, :get_with_massaging
  end
end

这不完全是你要求的,因为它只能深入一级 - 即x.questions[0].title需要x.questions[0][:title]

x = Myclass.get('http://api.stackoverflow.com/1.0/questions?tags=HTTParty')
p x.total
p x.questions[0][:title]

也许你可以想出这个答案和Joshua Creek的混合体来利用OpenStruct。

我还应该指出,如果你的方法没有命名为get,那么所有方法别名技巧都不是必需的。