Approaches to WebDav/CalDav on Rails, today and tomorrow.

I think that core is the right audience to bring this up.

As I was starting to work on a rails plugin to complement my ri_cal
gem, I thought that a simple CalDav server might make a neat source

But that got me thinking about how CalDav fits into Rails in its
current and future state.

WebDav can be thought of as an extended http which adds a handful of
new methods for manipulating resources and collections of resources.
CalDav further extends WebDav with two calendar specific methods for
creating and querying calendar resources.

I don't want to get into a religious discussion about whether or not
CalDav/WebDav is RESTful. FWIW Roy Fielding seems to think that
although the extensions aren't really necessary, WebDav (and
presumably CalDav) are more OK than some of the other things out there
on the interwebs.

Now in googling about, I discover that there's a railsdav plugin whose
usage I don't entirely understand.

One thing it does is to patch ActionController::AbstractRequest (or
ActionController::Request in Rails 2.3) to add the webdav methods to
the HTTP_METHODS constant. It's not clear whether this is enough to
allow routes to use the new methods as condititions or not.

It seems to me that this kind of patch is right where things are being
changed for Rails 3.

Would it be worthwhile to consider having an explicit extension API in
rails 3 to add 'http' methods in such a way that both dispatching and
routing takes the new methods into account?

I also notice that there is a rackdav project which provides a rack
middleware which understands webdav protocol. This appears to be
written as an 'endpoint' middle ware, it doesnt seem to provide for
passing through. This gave me that idea that another alternative to
adding methods to rails might be to interpose a rack middleware which
converted requests with webdav/caldav methods to requests with normal
http methods, by either rewriting the uri in some defined fashion
and/or adding parameters.

But that seems less compatible with the Rails approach, I think I'd
like to be able to route requests to different controllers/actions the
same way I can do with normal http rest schemes.


Unless something has changed since 2.2.2, adding to HTTP_METHODS is pretty much all that you need - see this article for an example:

I used this after about the tenth exception notifier message showed up in my mailbox on a Rails 2.2.2 app.

--Matt Jones

Actually that example is monkey-patching
ActionController::Routing::HTTP_METHODS, while the railsdav plugin
monkey originally monkey patched
ActionController::AbstractRequest::HTTP_METHODS, and was patched by
someone in a github fork to monkey patch
ActionController::Request::HTTP_METHODS because of a change in the
class name.

So looking at Rails 2.2.2 there are two constants named HTTP_METHODS.
The one in ActionController::Routing is used to determine whether a
method is valid when either setting up or recognizing routes. The one
in ActionController::AbstractRequest is used to validate the method in

In Rails 2.3 there are still those two HTTP_METHODS constants,
although as I noted ActionController::AbstractRequest is now
ActionController::Request, and there is now a THIRD
Rack::MethodsOverride::HTTP_METHODS constant which is used in the rack
middleware which Rails now uses to turn a post with a method override
to another type of request to validate the overriding method.

That's the kind of thing which makes me think that there should be one
place where the valid methods are defined consolidating the two/three
which are current, and a defined api for adding additional methods,
perhaps in environment.rb

I'd love to hear what the guys deep into the Rails 3 effort have to
say about this, since as I understand it, the goal is to define stable
APIs for extensions.