Ruby convert Object to Hash

前端 未结 17 1669
滥情空心
滥情空心 2020-12-12 10:35

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

相关标签:
17条回答
  • 2020-12-12 11:05

    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

    0 讨论(0)
  • 2020-12-12 11:07

    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 # }}}
    
    0 讨论(0)
  • 2020-12-12 11:08

    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

    0 讨论(0)
  • 2020-12-12 11:10

    Just say (current object) .attributes

    .attributes returns a hash of any object. And it's much cleaner too.

    0 讨论(0)
  • 2020-12-12 11:10

    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}
    
    0 讨论(0)
  • 2020-12-12 11:17

    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}}]}
    
    0 讨论(0)
提交回复
热议问题