我找到了相反的答案,但没有找到嵌套结构到JSON的方式
假设我有这个红宝石结构
Attributes = Struct.new :name, :preferredLanguage, :telephoneNumber, :timeZone
User = Struct.new :email, :service, :preferredLanguage, :attributes
我为Attributes
创建结构attributes = Attributes.new "Pedro", "es", "5555555", "Madrid"
# => #<struct Attributes name="Pedro", preferredLanguage="es", telephoneNumber="5555555", timeZone="Madrid">
attributes.to_h.to_json
# => "{\"name\":\"Pedro\",\"preferredLanguage\":\"es\",\"telephoneNumber\":\"5555555\",\"timeZone\":\"Madrid\"}"
Oj.dump attributes
# => "{\"^u\":[\"Attributes\",\"Pedro\",\"es\",\"5555555\",\"Madrid\"]}"
Oj.dump attributes, mode: :compat
# => "\"#<struct Attributes name=\\\"Pedro\\\", preferredLanguage=\\\"es\\\", telephoneNumber=\\\"5555555\\\", timeZone=\\\"Madrid\\\">\""
所以它运作良好,除非我使用gem Oj
,我无法删除对象的名称并获得与to_h.to_json
方法相同的
但是当我使用像用户
这样的嵌套Struct时会出现问题user = User.new "Pedro@email.com", "coolService", "es", attributes
# => #<struct User email="Pedro@email.com", service="coolService", preferredLanguage="es", attributes=#<struct Attributes name="Pedro", preferredLanguage="es", telephoneNumber="5555555", timeZone="Madrid">>
user.to_h.to_json
# => "{\"email\":\"Pedro@email.com\",\"service\":\"coolService\",\"preferredLanguage\":\"es\",\"attributes\":\"#<struct Attributes name=\\\"Pedro\\\", preferredLanguage=\\\"es\\\", telephoneNumber=\\\"5555555\\\", timeZone=\\\"Madrid\\\">\"}"
Oj.dump user, mode: :compat
# => "\"#<struct User email=\\\"Pedro@email.com\\\", service=\\\"coolService\\\", preferredLanguage=\\\"es\\\", attributes=#<struct Attributes name=\\\"Pedro\\\", preferredLanguage=\\\"es\\\", telephoneNumber=\\\"5555555\\\", timeZone=\\\"Madrid\\\">>\""
使用to_h.to_json
我得到属性对象的字符串,而使用oj,这不是有效的JSON。而且我还有另一个问题,有任何来自java的GSON,jackson库在ruby中以相同的方式工作
答案 0 :(得分:1)
如果你使用ActiveSupport(Rails),你可以开箱即用。当你似乎使用准系统Ruby时,只需递归地执行:
hashify = lambda do |struct|
as_hash = struct.to_h
struct_keys = as_hash.select { |_, v| v.is_a? Struct }.map(&:first)
struct_keys.each { |key| as_hash[key] = hashify.(as_hash[key]) }
as_hash
end
hashify.(user).to_json
# => "{\"email\":\"Pedro@email.com\",\"service\":\"coolService\",\"preferredLanguage\":\"es\",\"attributes\":{\"name\":\"Pedro\",\"preferredLanguage\":\"es\",\"telephoneNumber\":\"5555555\",\"timeZone\":\"Madrid\"}}"
至于GSON,似乎有a wrapper for Ruby,但我不认为它被广泛使用。 Rails的猴子修补行为足以满足99.99%的可能用途。如果要更改自定义序列化,还可以定义自定义序列化程序。