Creating nested hash from nested active record results

124 views
Skip to first unread message

Clem Rock

unread,
May 22, 2013, 10:53:14 AM5/22/13
to rubyonra...@googlegroups.com
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:

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

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:

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

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

--
Posted via http://www.ruby-forum.com/.

gsw

unread,
May 22, 2013, 3:12:43 PM5/22/13
to rubyonra...@googlegroups.com
Would this work?

MyModel.last.serializable_hash methods: MyModel.reflections.keys

Or is that too much?

Look at the options that you can pass into serializable_hash.

However, if you are doing this for json/etc. serialization in the controller, check out ActiveModel::Serializers.

gsw

unread,
May 22, 2013, 3:18:46 PM5/22/13
to rubyonra...@googlegroups.com
One note about this: this can hit n+1 queries pretty hard. Unless you put include: in your associations (which I wouldn't not recommend unless it makes sense, and it probably doesn't) you have to know at query time what to include (or use joins), and what I just posted would make that difficult.

If you do use ActiveModel::Serializers instead and have big serialized objects, look at yodo to help you identify the value for include: in your queries to avoid n+1:
https://github.com/garysweaver/yodo

You could also look at bullet in that regard:
https://github.com/flyerhzm/bullet

Clem Rock

unread,
Jan 2, 2014, 11:03:35 AM1/2/14
to rubyonra...@googlegroups.com
Just an FIY - this was my solution:

[code]
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
[/code]
Reply all
Reply to author
Forward
0 new messages