On Fri, Jul 20, 2012 at 11:43:12AM -0400, Jason Guiditta wrote:
On 20/07/12 11:32 -0400, Hugh O. Brock wrote:
On Fri, Jul 20, 2012 at 03:57:55PM +0100, Martyn Taylor wrote:
Hi gents,
There has been a few people raising similar questions around why are we not using the default rails renders and instead are using templates to render such things as xml. I've put together my reasoning on choosing this approach below:
I assume most people are aware that render :xml simply using a models to_xml method to parse the model.
There are a few issues with to_xml.
- to_xml uses elements for everything. In our API we use
attributes for special fields on our resources. These special fields are used to identify the resource and give its location. i.e. href and id.
We could extend to_xml to handle this for us. But there are some other issues.
- When returning lists and nested resources. For example:
<provider> <provider_account /> </provider>
or
<providers> <provider id='1' href='' /> <provider id='2' href='' /> </providers>
We do not want to return the full resource just a reference to it. This is to reduce the size of response body. to_xml will simply call to_xml on nested resources resulting in full resource representation.
- When rendering resources we only want to list its direct
children, not grandchildren. This is again to avoid sending whole object graphs in response bodies. Using to_xml will result in every resource in the graph being rendered.
- Templates are much more flexible.
All of the issues I described above could be implemented by overriding the to_xml method. Though it would get a little complicated.
Templates are much easier to maintain and update. In addition, using templates gives us more control on what we return on a individual model basis. For example we could have logic in our templates that say things like.
If STATUS == "Complete" then #don't return progress. etc....
To summarize. Yes you can use to_xml which is the standard way to render things like xml, json in rails. But there is a significant amount of work in implementing bespoke methods to make it work the way we need it to. Templates are much more flexible and are easier to implement. The downside of templates is that we have more files to maintain. But there is nothing complicated about templates they are extremely trivial.
An additional point in support of not using to_xml -- if you override it in the model, now you have a bunch of effectively presentation code in your model. Yuck.
(you can use a decorator class to avoid this, but frankly I like the template approach used here better.)
Funny, I just started this same debate in irc, though I favor the decorator approach, I think it is a cleaner separation of concerns, and addresses your point about view logic in the model. That said, I personally think there should be as little logic in the views as possible. Some of that logic may well belong in the model, some in a presenter/decorator type pattern. Also, I put forward the idea that perhaps templates could be used _in conjuction_ with decorator objects.
I've only played with decorators a little bit but it does seem like a really nice pattern (I used the Draper gem). You instantiate the decorator object in the controller like you would a model object and call the various controller/view-space helper methods just by adding "h." in front.
The nice thing is, done properly, it can free you from things like "case object when User ... when Halibut ... when Cloud..." in helpers. You still need one such thing to get the correct decorator for a class when you don't know the object typ, but you just stick it in the ApplicationDecorator base class and be done with it.
Anyway it seems worth looking into. The good news is it's the kind of thing you could add gradually -- it doesn't require a wholesale change to the new way of grabbing model objects.
--H