Rubyでネストされたオブジェクトをjsonに変換する方法

6546 ワード

JSONはデータ構造が簡単で便利であるため、インターネット上の主流のデータ交換のデータフォーマットとなっている.
ネストされたオブジェクト(Nested Object)のJSON変換方法を議論する前に,簡単なruby JSON変換を見てみよう.まず、rubyオブジェクトはJSON文字列に変換されます.
 
  
class Obj1

    def initialize(var1)

        @var1 = var1

    end


    def to_json(*a)

        {

            "json_class" => self.class,

            "data" => {"var1" => @var1}

        }.to_json(*a)

    end


    def self.json_create(json_str)

        new(json_str["data"]["var1"])

    end

end


obj1 = Obj1.new("i am obj1")


#obj1 to JSON string

json_str = obj1.to_json

puts "JSON string of obj1 = #{json_str}"


#JSON string to obj1

obj11 = JSON.parse(json_str)

puts "ob1 from json string = #{obj11.var1}"


上のコードでは、rubyとJSON stringの間の変換には、3つのポイントがあります.
#jsonライブラリを導入してこそ、open class方式でHashオブジェクトにto_を付ける2つの方法があります.json(*a)メソッド、rubyのopen classについてOpen Class特性をサポートするプログラミング言語における開閉原則(Open-Closed Principle)1)require'json'を参照
#定義オブジェクトをJSON stringのto_に変換json(*a)メソッドは,Hashオブジェクトを用いたto_を実現する.json(*a)メソッド2)def to_json(*a)
#JSON stringからオブジェクトを構築するjson_を定義するcreateメソッド、このメソッドはクラスメソッド3)def self.json_create(json_str)
上の3点はRubyにおけるJSON string相互変換を実現するための基本的な要件である.
コード実行結果:
 
  
JSON string of obj1 = {"json_class":"Obj1","data":{"var1":"i am obj1"}}

ob1 from json string = i am obj1


次に、ネストされたオブジェクトのJSON string変換を見てみましょう.
 
  
#!/usr/local/ruby/bin/ruby


require 'json'


class Obj1

    def initialize(var1)

        @var1 = var1

    end


    def to_json(*a)

        {

            "json_class" => self.class,

            "data" => {"var1" => @var1}

        }.to_json(*a)

    end


    def self.json_create(json_str)

        new(json_str["data"]["var1"])

    end


    attr_reader :var1

end


class Obj2

    def initialize(var2)

        @var2 = var2

    end


    def to_json(*a)

        {

            "json_class" => self.class,

            "data" => {"var2" => @var2}

        }.to_json(*a)

    end


    def self.json_create(json_str)

        new(json_str["data"]["var2"])

    end


    attr_reader :var2

end


class Obj

    def initialize(obj1, obj2)

        @obj1 = obj1

        @obj2 = obj2

    end


    def to_json(*a)

        {

            "json_class" => self.class,

            "data" => {"obj1" => @obj1.to_json, "obj2" => @obj2.to_json}

        }.to_json(*a)

    end


    def self.json_create(json_str)

        new(json_str["data"]["obj1"], json_str["data"]["obj2"])

    end


    def to_s

        "Hi, i am obj"

    end


    attr_reader :obj1, :obj2

end


obj1 = Obj1.new("i am obj1")

obj2 = Obj2.new("i am obj2")

obj = Obj.new(obj1,obj2)


obj_json_str = obj.to_json

puts "JSON string of obj = #{obj_json_str}"


obj_1 = JSON.parse(obj_json_str)

puts "obj_1 from json string , obj1.class = #{obj_1.obj1.class}, obj2.class = #{obj_1.obj2.class}"


上のコードでは、オブジェクトをネストする慣性思考は、まずオブジェクト自身をJSON stringに変換します.
 
  
"data" => {"obj1" => @obj1.to_json, "obj2" => @obj2.to_json}

上のコード出力:
 
  
JSON string of obj = {"json_class":"Obj","data":{"obj1":"{\"json_class\":\"Obj1\",\"data\":{\"var1\":\"i am obj1\"}}","obj2":"{\"json_class\":\"Obj2\",\"data\":{\"var2\":\"i am obj2\"}}"}}

obj_1 from json string , obj1.class = String, obj2.class = String


ネストされたオブジェクトがJSON stringに変換されると、反スラッシュ:
 
  
JSON string of obj = {"json_class":"Obj","data":{"obj1":"{\"json_class\":\"Obj1\",\"data\":{\"var1\":\"i am obj1\"}}","obj2":"{\"json_class\":\"Obj2\",\"data\":{\"var2\":\"i am obj2\"}}"}}

また、JSON string変換後、objオブジェクトにネストされたオブジェクトobj 1およびobj 2は、いずれも所望のObj 1およびObj 2タイプではなくStringである
 
  
obj_1 from json string , obj1.class = String, obj2.class = String

実際、ここは慣性思考の被害者で、ネストされた対象で、そのto_を呼び出す必要はありません.jsonメソッド.だからObjクラスのto_jsonコード:
 
  
    def to_json(*a)

        {

            "json_class" => self.class,

            "data" => {"obj1" => @obj1.to_json, "obj2" => @obj2.to_json}

        }.to_json(*a)

    end


次のように修正します.
 
  
    def to_json(*a)

        {

            "json_class" => self.class,

            "data" => {"obj1" => @obj1, "obj2" => @obj2}

        }.to_json(*a)

    end


次に、コードを実行すると、予想される出力が表示されます.
 
  
JSON string of obj = {"json_class":"Obj","data":{"obj1":{"json_class":"Obj1","data":{"var1":"i am obj1"}},"obj2":{"json_class":"Obj2","data":{"var2":"i am obj2"}}}}

obj_1 from json string = {"json_class"=>"Obj", "data"=>{"obj1"=>#, "obj2"=>#}}