Modifying the default to_xml

Hey all,

I’ve been struggling with the default way that rails generates XML
representations of things. Specifically, I have a tableless model that
I use to handle my searches (they return more than simply a collection
of results). I was struggling with this until I remembered that I can
simply use action.xml.builder to create my specific XML
representations.

However.

I’m not sure that I want to do this for all my ActiveRecord models.
I’d much rather modify the default way that the to_xml works, or even
creating a new to_adams_xml (or something) and configure my
controllers to use that.

But I’m not at all sure how I should go about doing that. Can someone
point me at some tutorials that will give me some hints as to where I
need to head?

Thanks!
Adam

why not simply overwrite the to_xml method?

On May 27, 8:41 am, Thorsten M. <rails-mailing-l…@andreas-
s.net> wrote:

why not simply overwrite the to_xml method?

That’s the obvious approach; I should have used “Overwriting to_xml”
as my subject.

My real question, which I wasn’t clear about, is really, “given that I
want to overwrite the to_xml for ActiveRecord, what is the best way to
do this?”

I could create a to_xml for each of my models but that begs the
question, why not simply use an action.xml.builder view? Indeed, I
think that would be the appropriate place to do it.

I’m looking to make the change to ActiveRecord itself. There are
probably a dozen ways to do it but I want to know the best way.

So I’m not really asking, “what should I do?” but rather, “how should
I do it?”

Adam

AdamV wrote:

On May 27, 8:41 am, Thorsten M. <rails-mailing-l…@andreas-
s.net> wrote:

why not simply overwrite the to_xml method?

That’s the obvious approach; I should have used “Overwriting to_xml”
as my subject.

My real question, which I wasn’t clear about, is really, “given that I
want to overwrite the to_xml for ActiveRecord, what is the best way to
do this?”

I could create a to_xml for each of my models but that begs the
question, why not simply use an action.xml.builder view? Indeed, I
think that would be the appropriate place to do it.

I’m looking to make the change to ActiveRecord itself. There are
probably a dozen ways to do it but I want to know the best way.

So I’m not really asking, “what should I do?” but rather, “how should
I do it?”

Adam

Doing a to_xml on an active record object straddles a blurry line beween
data and presentation. The simple answer is to just make a new to_xml
method on everything that needs it. You can actually use builder
outside of a view. I would do this:

def to_xml
returning ‘’ do |output|
xml = Builder::XmlMarkup.new(:target => output, :indent => 2)
xml.foo {
xml.bar “Foo and Bar make FooBar”
}
end
end

The trouble is that the way rails works, template renderers are not
available everywhere. So you can’t do this:

def to_xml
render :partial => ‘thingy.xml’, :locals => { :thingy => self }
end

Although that might be cleaner. The other approach is a presenter
object. I’m not too familiar approach, but a presenter cleans up the
model → view interface. Things like an XML view would reside in a
presenter for that model. That is then presented to the view for
rendering, without adding noise to your models. But one way may look
like this:

def presenter
@presenter ||= Thingy::Presenter.new(self)
end

def to_xml
@presenter.to_xml
end

Your presenter can then handle retrieving other view-centric data. If
you create a method on your model, that you only use in the view, then
that would probably be a good presenter method.

But, really, you are probably fine just using Builder directly in your
model.

Maybe if I explain myself a bit better, I 'll get some more feedback
from people.

I’ve been thinking a lot about what a restful interface should look
like and I’ve been primarily looking at Rails’ implementation. As I’ve
been thinking about it, and looking at Roy Fielding’s talk on the
subject, I think that there is something missing with the XML
serialization in rails. This is based on my observations of how Rails
seems to be creating its XML representations.

The issue concerns associated objects; the has_many and belongs_to
crowd. According to my understanding of Roy’s presentation (I’ll read
his dissertation, I promise), a representation of a resource exposes
its associated resources through its URL.

Let me give an example. Lets say I have the following models:

class Blog < ActiveRecord::Base
belongs_to :author
end

class Author < ActiveRecord::Base
has_many :blogs
end

Assuming that these are both resources, you’ll get something like:

GET /blogs/1.xml

1 My Blog 1

GET /authors/1.xml

1 Adam

From Roy’s presentation I think that the “REST Way” to do things would
be more like:

GET /blogs/1.xml

My Blog

GET /authors/1.xml

Adam

I might also put the URI in an element but this way seems a lot more
compact. Besides, the URI is really metadata in this sense.

I think that this approach has a number of advantages. First is
polymorphism. Not that it wouldn’t be challenging for your framework
to handle but the following member representation seems very
compelling (I’m going to skip the type attributes as I think they’re
tedious for examples):

Jim B.

I’ve represented a polymorphic association without having to express
what types the members are. I can determine that when I retrieve the
associated representations.

The second advantage is crossing the domain boundary. I was thinking
that it might be nice to refer to members by their Open ID uri but I
suspect that might not be a good example. However, we might extend or
previous example a bit:

Jim B.

Depending on what is consuming your API that may or may not be
problematic. I wouldn’t see a problem with this if I was building a
JavaScript application to consume the XML. Perhaps if you could
associate an ActiveResource with an XML Schema rather than a URL, this
would be feasible in Rails.

Since not all associated objects are made into resources (for instance
join objects for has_many :through), those associations should be
realized directly in the XML representation (I believe the :include
option does this now).

So back to my questions. I want to be able to do all this without
having to create view files for each model I create. Instead I want to
create a plugin that modifies how to_xml works to give me the
behaviour I want. The only problem is that I’m having a hard time
getting my head around which methods of which classes I need to
override to get all this to happen.

Thanks!
Adam

On May 27, 8:22 pm, Alex W. [email protected]
wrote:

Clearly, you finished your reply before I finished my elaboration.

Thanks, that will help a lot.