Creating nested hash from nested active record results

Hello,
I’m trying to find a very abstract and “one size fits all” for converting nested active record results to nested hashes. It’s easy, to do one level deep as such:


results_to_hash = Hash[ found_categories.map{ |c| [c.id, c.title]}]

But, when I try to add another collection to the mix, it completely borks and the results_to_hash only returns an empty hash IE:


results_to_hash = Hash[ found_categories.map{ |c| [c.id, c.title, c.categories]}]

Ultimately, I’d like it to be smart enough to detect if a model object contains a collection (IE: object.class.reflect_on_all_associations), and automatically convert those to hashes.

Any ideas?

Thanks,
Eric

I’d first reach for something like jbuilder for this and be explicit about what properties you want to include.

Another option is to include nested models in a method like to_json

found_categories.to_json(:include => :categories)

If it’s a tree structure you’re trying to build out I’d reach for a gem like ancestry to build the nested hash for you.

Hope it helps :slight_smile:

Just an FIY. This is the method I came up with:


   def self.active_record_to_array_of_hashes(array_collection, sub_collection_names=[])
     hashed_collection = []
     array_collection.each do |obj|   
       tmp_hash = ActiveSupport::JSON.decode(obj.to_json)
     
       #### hashify specified model association
       sub_collection_names.each do |name| 
         if(obj.class.reflections.keys.include?(name))
           tmp_hash[name] = ActiveSupport::JSON.decode(obj.send(name).to_json)
         end
       end
       hashed_collection << tmp_hash
     end
     return hashed_collection
   end