Let\'s say I have a Gift
object with @name = \"book\"
& @price = 15.95
. What\'s the best way to convert that to the Hash {na
You should override the inspect
method of your object to return the desired hash, or just implement a similar method without overriding the default object behaviour.
If you want to get fancier, you can iterate over an object's instance variables with object.instance_variables
If you need nested objects to be converted as well.
# @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 # }}}
You can use as_json
method. It'll convert your object into hash.
But, that hash will come as a value to the name of that object as a key. In your case,
{'gift' => {'name' => 'book', 'price' => 15.95 }}
If you need a hash that's stored in the object use as_json(root: false)
. I think by default root will be false. For more info refer official ruby guide
http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json
Just say (current object) .attributes
.attributes
returns a hash
of any object
. And it's much cleaner too.
To do this without Rails, a clean way is to store attributes on a constant.
class Gift
ATTRIBUTES = [:name, :price]
attr_accessor(*ATTRIBUTES)
end
And then, to convert an instance of Gift
to a Hash
, you can:
class Gift
...
def to_h
ATTRIBUTES.each_with_object({}) do |attribute_name, memo|
memo[attribute_name] = send(attribute_name)
end
end
end
This is a good way to do this because it will only include what you define on attr_accessor
, and not every instance variable.
class Gift
ATTRIBUTES = [:name, :price]
attr_accessor(*ATTRIBUTES)
def create_random_instance_variable
@xyz = 123
end
def to_h
ATTRIBUTES.each_with_object({}) do |attribute_name, memo|
memo[attribute_name] = send(attribute_name)
end
end
end
g = Gift.new
g.name = "Foo"
g.price = 5.25
g.to_h
#=> {:name=>"Foo", :price=>5.25}
g.create_random_instance_variable
g.to_h
#=> {:name=>"Foo", :price=>5.25}
Recursively convert your objects to hash using 'hashable' gem (https://rubygems.org/gems/hashable) Example
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}}]}