查找类属性类的最佳方法

时间:2016-03-25 07:45:31

标签: ruby json object

我用Ruby砸岩石,但我一直在战斗。 今天我遇到了识别属性的问题。

我正在将对象序列化为JSON,我的对象看起来像这样,其中属性Items是一个对象,其中包含Item类型的对象,而address是一个对象。

    module OrderSet
  class OrderObject

    attr_accessor :items, :url, :email, :address, :id

    def initialize args = nil
      if args != nil
        args.each do |k, v|
          instance_variable_set("@#{k}", v) unless v.nil?
        end
      end
    end

    def to_json
      hash = {}
      self.instance_variables.each do |var|
        # [1..-1] is to get rid of the leading @ from instance variables. This is so the API knows the variables.
        hash[var[1..-1]] = self.instance_variable_get var
      end
      hash.to_json
    end
  end
end

如果我对此进行序列化,最终会得到一个像这样的JSON(抱歉这个混乱,但它不会格式化,因为它不是一个有效的JSON ......:

"{"address":"{\"name\":\"Ruby\",\"line1\":\"StoneStreet\",\"city\":\"Gemstones\",\"country\":\"The WOrld\",\"postCode\":\"4004VC\"}","items":"[\"{\\\"productId\\\":\\\"canvas_a60x60\\\",\\\"files\\\":\\\"{\\\\\\\"content\\\\\\\":\\\\\\\"http://i.imgur.com/uHZfjIU.jpg\\\\\\\"}\\\",\\\"quantity\\\":10,\\\"pageCount\\\":1,\\\"metaData\\\":\\\"test\\\"}\"]","email":"test@test.test"}"

如何看待: "{"address":"{"name":"Ruby", "line1":"StoneStreet", "city":"Gemstones", "country":"The WOrld", "postCode":"4004VC" }","items":"["{
"productId":"canvas_a60x60", "files":"{"content":"http://i.imgur.com/uHZfjIU.jpg" }","quantity":10, "pageCount":1, "metaData":"test" }"]", "email":"test@test.test" }"

现在每个类都有自己的to_json方法,需要调用它并将其放入原始to_json方法的哈希值中。我想出了一些解决方案:

  1. 执行object.is_a?(ClassName)
  2. 检查模块(我有4个模块,总共包含20个类,所以第一个比第二个更长)
  3. 创建一个基础对象,将所有其他对象扩展到该对象,检查它是否是基础对象的子对象并相应地调用to_json(将to_json放在parrent中)
  4. 也许是一种静态方法,但我不知道它是否会像调用instance_variables
  5. 一样工作

    [编辑] woops,忘了问这个问题,有没有比上面提到的更好的方法,如果不是,上面哪个是最好的?

1 个答案:

答案 0 :(得分:1)

由于您正在使用大量的元编程,作为一个简单的测试,尝试并编写您期望实际发生的所有内容:

def to_json
  hash = {}
  hash["address"] = @address
  hash.to_json
end

从那里,尝试找出你的错误所在。

编辑:

例如:

class Address
  def to_json(options={})
    {"name" => "foo"}.to_json
  end
end

order_set = OrderSet::OrderObject.new({"address" => Address.new })
order_set.to_json

这就是你要追求的吗?

module JSONable
  def to_json(options={})
    hash = {}
    self.instance_variables.each do |var|
      hash[var[1..-1]] = self.instance_variable_get var
    end
    hash.to_json
  end
end


class Address
  include JSONable
  # Rest of code
end