Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RoR nested :include to include sub-resources in to_xml/to_json

I have a weird data model situation to start with, so maybe my whole approach is wrong. Here's what I'm doing:

I have a class called Bird and a simple class called Color. Conceptually, each bird has two to_many associations to Color, one for male colors and one for female colors. The way I've handled this is to use a join model called BirdColoration that belongs to a bird and a color and has an additional boolean field to tell if the coloration is for male or female. So each bird actually has a to_many relationship to BirdColoration as well as a to_many to Color :through BirdColoration. If this sounds reasonable, then continue reading. Otherwise, stop and tell me why it's wrong!

I need to be able to dump the birds table as json. Previously, when each bird only had one to_many association to colors, I could just use :include to include each bird's colors in the json dump. Now, I'm including the BirdColorations in the dump, but I still need to get at the color models themselves. I could separately include each bird's colors and colorations and then match them up while parsing, but I would much rather just include each coloration's color directly. Something like

      format.json  { render :json => @birds.to_json(:include => [{:bird_colorations => :color}, :seasons, :habitats, :image_holders]) }

The above doesn't work, however. I think that this should be possible. Can anyone point me in the right direction for how to handle this?

For now, I'll just include each bird's color and colorations separately and match them up in parsing. At least I know that will work.

Thanks!

like image 446
CharlieMezak Avatar asked Dec 14 '10 19:12

CharlieMezak


1 Answers

I found the answer here. The syntax for the :include option in to_xml and to_json is different than that for ActiveRecord's find method. To include nested resources in this way, you pass in a hash instead of an array. The correct method call for me looks like:

      format.json  { render :json => @birds.to_json(:include => {:bird_colorations => {:include => :color}, :seasons => {}, :habitats => {}, :image_holders => {}}) }

Compare to the one in my question to see the difference. For resources for which you don't want to include sub-resources, just pass an empty hash as the value for it's symbolized name.

Live and learn!

like image 58
CharlieMezak Avatar answered Sep 28 '22 04:09

CharlieMezak