March 6, 2008 11:56 am

So you’re out in Rails-land and you’re trying to start using ActiveResource, since it’s neat. But you’ve got a really gnarly ActiveRecord model on the server side with a whole bunch of associations that you need to send along to the client (or consumer, in other terminology), and somehow you can’t quite figure out the syntax to do it all. You’ve read the Rails documentation for to_xml but that only talks about first-level associations using :include and that’s pretty great, but you’d love to send along that second level association. And the third. And…

As it turns out this is possible, however, it is not really documented in a convenient location. By UTSL, you can find that serializing an ActiveRecord object (either to_xml or to_json) can actually go to an arbitrary depth.

Let’s say you’ve got a model, Employee. This employee has_one :address, and also has_many :managers, Office Space-style. To dump these first level associations, you’ll use :include, like so:

employee.to_xml(:include => [:address, :managers])

Nifty. But the client you’re trying to write is actually an address list, and you’d like to include all of the managers’ addresses as well. The :include option can actually take a hash instead of an array, and this hash is full of all the same options you’d pass to to_xml at the top level.

employee.to_xml(:include => {:address, :managers => {:include => [:address]}})

Awesome, now the managers’ addresses will be serialized along with everything else. Just to demonstrate a few other options, let’s say that though the managers are all pointy-haired, the company has relabeled them as “friends” in an attempt to improve morale. So instead of the list containing a managers group, you want it to contain a friends group. The model is the same though, the managers aren’t really friends, they’re still managers. We’re just relabeling them:

employee.to_xml(:include => {:address => {}, :managers => {:root => 'friends', :include => [:address]}})

It’s worth noting that Rails is smart enough to singularize the root for each of the collection’s elements. So even though we’ve specified “friends” above, each element will be “friend”. This works for odd pluralizations, like “categories” to “category”. Thanks Rails!

There are a ton of other options for serialization, and they’re all pretty neat! This ability to specify options to sub-elements isn’t documented in an easily-accessible location (I couldn’t find it, anyway), and it’s pretty useful. So have fun.

3 Responses to “Rails 2.0 to_xml”

tomer doton says:
June 12th, 2008 at 2:42 am

this is great, thanks. however, looks like there is a syntax error in the above you are missing/have an extra curly

tomer doron says:
June 12th, 2008 at 7:10 pm

okay, got it…your middle example should be:

employee.to_xml(:include => {:address => {}, :managers => {:include => [:address]}})

Lalit K. Shandilya says:
June 29th, 2009 at 12:46 am

Thanks for posting these details about :to_xml.

Your tip on publishing managers as friends saved me couple of hours. It’s not even mentioned in the APIs