Ruby on rails 什么';让HttpParty返回对象/类而不是JSON响应的最简单方法是什么?

Ruby on rails 什么';让HttpParty返回对象/类而不是JSON响应的最简单方法是什么?,ruby-on-rails,ruby,ruby-on-rails-4,httparty,Ruby On Rails,Ruby,Ruby On Rails 4,Httparty,现在我呼吁: def child(parent_id, child_id, params = {}) if @api_token self.class.get("/parents/#{parent_id}/children/#{child_id}", query: params, :headers=>{"Authorization"=>"Token token=#{@api_token}"}) else self.c

现在我呼吁:

def child(parent_id, child_id, params = {})
  if @api_token
    self.class.get("/parents/#{parent_id}/children/#{child_id}", query: params,
                      :headers=>{"Authorization"=>"Token token=#{@api_token}"})
  else
    self.class.get("/parents/#{parent_id}/children/#{child_id}", query: params)
  end
end
它以散列形式直接从API返回JSON响应。对于我来说,有没有一种简单的方法来标准化响应,以便它解析JSON并生成一个类

例如:

Original Response
--------
{'child' : { 'name' : 'John Doe', 'age' : 23 } }

Desired Response
--------
res.name # John Doe
res.age  # 23
res.class # APIClient::Child

它可以通过传递给请求调用的自定义解析器来实现(不过我强烈建议不要这样做,保持现在的状态)

可以传递的解析器示例如下

class InstanceParser < HTTParty::Parser
  def parse
    #assuming you always have a json in format { 'one_key_mapping_to_model' => data }        
    body_as_json = JSON.parse(body) #string parsed to json        

    model_class_name = body_as_json.keys.first # == 'one_key_mapping'       
    model_class_data = body_as_json[model_class_name] # == data
    class_instance = model_class_name.camelize.constantize.new(model_class_data) # will create new instance of OneKeyMapping

    class_instance
  end
end
类InstanceParserdata} body_as_json=json.parse(body)#解析为json的字符串 model_class_name=body_as_json.keys.first#==“一个键映射” model_class_data=body_as_json[model_class_name]#==data class_instance=model_class_name.camelize.constantize.new(model_class_data)#将创建OneKeyMapping的新实例 类实例 结束 结束
然后在api调用pass
self.class.get(“/parents/{parent\u id}/children/{child\u id}”)中,查询:params,解析器:InstanceParser)

将散列传递给初始值设定项

class APIClient::Child
  attr_accessor :foo, :bar

  def initialize(hash = {})
    hash.each do |k,v|
      public_send("#{k}=", v)
    end
  end
end
然后在API客户端中,您将在响应和对象之间映射:

def child(parent_id, child_id, params = {})
  opts = { query: params }
  opts.merge!(:headers=>{"Authorization"=>"Token token=#{@api_token}"}) if @api_token
   begin 
    res = self.class.get("/parents/#{parent_id}/children/#{child_id}", opts)
    case response.code
      when 200
        APIClient::Child.new(res[:child])
      when 404
        # not found - raise some sort of error that the API client consumer 
        # can catch maybe?
      else
        # probably just log it since there is little we can do here.
    end      
   rescue HTTParty::Error
     # probaly just log it. Could be a connection error or something else.
   end
end

这可能没有您所希望的那么神奇,但是如果不在HTTP请求和适合消费的对象之间进行映射,API客户机的角色是什么呢。这里的大多数boooring样板代码在传递令牌和处理错误时都可以外包给父类或模块。

我在考虑使用hashie。但随后,我看到了返回根节点所需的
res.class
。哈西在这里可能帮不了什么忙。我猜,也许你可以扩展hashie的API,使其符合你的需要?@bsvin33t hashie可能不是个坏主意。我真的不需要.class,只是认为它有效地说明了这个概念。请注意,如果您不真正关心声明和记录您创建的对象的属性,您可以简单地使用
OpenStruct
或让您的
APIClient::Child
扩展
OpenStruct