Non ci sono metodi predefiniti per realizzare tale compito, perché il built-in #to_hash
restituisce la rappresentazione Hash ma non profonda converte i valori.
Se un valore è OpenStruct
, viene restituito come tale e non viene convertito in Hash
.
Tuttavia, questo non è così complicato da risolvere. È possibile creare un metodo che attraversa ogni chiave/valore in un'istanza OpenStruct
(ad esempio utilizzando each_pair
), discende in modo ricorsivo negli OpenStruct
nidificati se il valore è OpenStruct
e restituisce un Hash
di tipi di base solo Ruby.
Tale Hash
può quindi essere serializzato facilmente utilizzando .to_json
o JSON.dump(hash)
.
Questo è un esempio molto breve
def openstruct_to_hash(object, hash = {})
object.each_pair do |key, value|
hash[key] = value.is_a?(OpenStruct) ? openstruct_to_hash(value) : value
end
hash
end
openstruct_to_hash(OpenStruct.new(foo: 1, bar: OpenStruct.new(baz: 2)))
# => {:foo=>1, :bar=>{:baz=>2}}
fonte
2015-10-13 00:19:33
Grazie per la risposta dettagliata! Mi sento illuminato ora! Sembra che 'to_json' sia piuttosto zoppo in questo aspetto dal momento che si spera che tu possa convertire ricorsivamente in JSON. E perché 'OpenStruct' ha un metodo' to_json'? – Breedly
'to_json' è un'abitudine (cattiva?) Resa popolare dalla pigrizia dei programmatori. È molto semplice chiamare '.to_json', così semplice che spesso si dimentica che avere tali metodi globali richiede che ogni possibile oggetto lo implementa o cada all'implementazione standard. Ogni volta che si usano oggetti complessi, è meglio essere espliciti (o usare direttamente JSON o per oggetti più complessi come i modelli ActiveRecord usare un serializzatore). –
Puoi indicarmi ulteriori informazioni su questo? – Breedly