logo - Ruby convert Object a hash
hbase (16)
Convierta recursivamente sus objetos en hash usando la gema ''hashable'' ( https://rubygems.org/gems/hashable )
class A
include Hashable
attr_accessor :blist
def initialize
@blist = [ B.new(1), { ''b'' => B.new(2) } ]
end
end
class B
include Hashable
attr_accessor :id
def initialize(id); @id = id; end
end
a = A.new
a.to_dh # or a.to_deep_hash
# {:blist=>[{:id=>1}, {"b"=>{:id=>2}}]}
Digamos que tengo un objeto de Gift
con @name = "book"
y @price = 15.95
. ¿Cuál es la mejor manera de convertir eso a Hash {name: "book", price: 15.95}
en Ruby, no Rails (aunque no dude en dar la respuesta de Rails también)?
Debe anular el método de inspect
de su objeto para devolver el hash deseado o simplemente implementar un método similar sin anular el comportamiento predeterminado del objeto.
Si quieres ser más elegante, puedes iterar sobre las variables de instancia de un objeto con object.instance_variables
Deberías probar Hashie, una joya maravillosa: https://github.com/intridea/hashie
Es posible que desee probar instance_values
. Eso funcionó para mí.
Gift.new.attributes.symbolize_keys
Implementar #to_hash
?
class Gift
def to_hash
hash = {}
instance_variables.each {|var| hash[var.to_s.delete("@")] = instance_variable_get(var) }
hash
end
end
h = Gift.new("Book", 19).to_hash
Para objetos de registro activo
module ActiveRecordExtension
def to_hash
hash = {}; self.attributes.each { |k,v| hash[k] = v }
return hash
end
end
class Gift < ActiveRecord::Base
include ActiveRecordExtension
....
end
class Purchase < ActiveRecord::Base
include ActiveRecordExtension
....
end
y luego solo llama
gift.to_hash()
purch.to_hash()
Produce una copia superficial como un objeto hash de solo los atributos del modelo
my_hash_gift = gift.attributes.dup
Verifica el tipo del objeto resultante
my_hash_gift.class
=> Hash
Puede escribir una solución muy elegante usando un estilo funcional.
class Object
def hashify
Hash[instance_variables.map { |v| [v.to_s[1..-1].to_sym, instance_variable_get v] }]
end
end
Puedes usar el método as_json
. Convertirá tu objeto en hash.
Pero, ese hash vendrá como un valor para el nombre de ese objeto como una clave. En tu caso,
{''gift'' => {''name'' => ''book'', ''price'' => 15.95 }}
Si necesita un hash almacenado en el objeto, use as_json(root: false)
. Creo que por defecto root será falso. Para obtener más información, consulte la guía oficial de rubí
http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json
Si necesita convertir objetos anidados también.
# @fn to_hash obj {{{
# @brief Convert object to hash
#
# @return [Hash] Hash representing converted object
#
def to_hash obj
Hash[obj.instance_variables.map { |key|
variable = obj.instance_variable_get key
[key.to_s[1..-1].to_sym,
if variable.respond_to? <:some_method> then
hashify variable
else
variable
end
]
}]
end # }}}
Si no está en un entorno Rails (es decir, no tiene ActiveRecord disponible), esto puede ser útil:
JSON.parse( object.to_json )
Solo diga (objeto actual). .attributes
.attributes
devuelve un hash
de cualquier object
. Y es mucho más limpio también.
Gift.new.instance_values # => {"name"=>"book", "price"=>15.95}
class Gift
def initialize
@name = "book"
@price = 15.95
end
end
gift = Gift.new
hash = {}
gift.instance_variables.each {|var| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
p hash # => {"name"=>"book", "price"=>15.95}
Alternativamente con each_with_object
:
gift = Gift.new
hash = gift.instance_variables.each_with_object({}) { |var, hash| hash[var.to_s.delete("@")] = gift.instance_variable_get(var) }
p hash # => {"name"=>"book", "price"=>15.95}
class Gift
def to_hash
instance_variables.map do |var|
[var[1..-1].to_sym, instance_variable_get(var)]
end.to_h
end
end