2012-12-03 39 views
0

有沒有辦法讓JSON生成的字符串保持屬性名稱?從這個模型:如何讓JSON保持類屬性名稱?

class Person 
    attr_accessor :name 

    def self.json_create(o) 
     new(*o['data']) 
    end 

    def to_json(*a) 
     { 'json_class' => self.class.name, 'data' => [name] }.to_json(*a) 
    end 
end 

JSON生成字符串:

{ 
    "json_class": "Person", 
    "data": ["John"] 
} 

,但我想這樣的字符串:

{ 
    "json_class": "Person", 
    "data": 
    { 
     "name" : "John" 
    } 
} 

有沒有辦法做到這一點,仍然能夠通過名稱訪問屬性?像:

person.name 
+0

是的,你說得對。我已經編輯過,所以現在確定。 mikhailvs感謝您的幫助。 – Juliano

+0

試試這個:'JSON.parse(person.to_json(methods:[:name]))' – zx1986

+0

或'person.as_json(methods :: name)' – zx1986

回答

1

你可以通過完整的屬性,而不是指定 '名':

def to_json(*a) 
    { 'json_class' => self.class.name, 'data' => attributes }.to_json(*a) 
end 

如果您想篩選出特定的屬性,你可以這樣做:

def to_json(*a) 
    attrs_to_use = attributes.select{|k,v| %[name other].include?(k) } 
    { 'json_class' => self.class.name, 'data' => attrs_to_use }.to_json(*a) 
end 

而且如果你只是想用'名字',然後寫出來:)

def to_json(*a) 
    { 'json_class' => self.class.name, 'data' => {:name => name} }.to_json(*a) 
end 

UPDATE

澄清會如何做一個初始化處理所有的屬性,你可以做這樣的事情:

class Person 
    attr_accessor :name, :other 

    def initialize(object_attribute_hash = {}) 
    object_attribute_hash.each do |k, v| 
     public_send("#{k}=", v) if attribute_names.include?(k) 
    end 
    end 

    def attribute_names 
    %[name other] # modify this to include all publicly assignable attributes 
    end 

    def attributes 
    attribute_names.inject({}){|m, attr| m[attr] = send(attr); m} 
    end 

    def self.json_create(o) 
    new(o['data']) 
    end 

    def to_json(*a) 
    { 'json_class' => self.class.name, 'data' => attributes }.to_json(*a) 
    end 
end 
+0

OK。但是當我解析它來組裝Person對象並嘗試訪問我得到的name屬性時: 'p = JSON.parse(json_str)' 'puts p.name' 'name' 'John' I希望它只輸出不是兩個值的字符串。爲什麼會這樣呢? – Juliano

+0

我想這樣,當從JSON字符串解析回來時,屬性「name」變成了數組''「name」,「John」]'。我錯過了什麼? – Juliano

+0

你的'json_create'方法是使用'new(* o ['data'])'將數據散列'散佈到數組中。爲了避免這種情況,省略星號:'new(o ['data'])' – PinnyM