Challenges with RJS and Redirection

There are always serious conceptual challenges with building a large
system, especially when you want to keep the responsibilities of each
component clear and with as few side-effects as possible.

There’s one controller action in the not-so-stealth-anymore project
(GiftLasso) I’m working on that begins multiple workflows. Naturally,
we’ve been using Bruce Williams’ wonderful in_context plugin for
most of these issues. The main point of this action is to create (or
find) a model — I’ll call it model A — that needs to be present for
the subsequent action. Once this first model is created, we redirect
to the new action of the next controller so that the user can input
some information and then create the associated model (Model B). Our
application is CRUD-focused but doesn’t use REST as of yet. In the
future, I’d prefer to create model A as we’re creating model B, but
the separation works well for now and is conceptually cleaner.
That pattern worked very nicely and cleanly until we wanted to add a
little Ajax in the mix. The idea was to add pop-over boxes so that
the user could stay in the same page, browsing through lists of Model
A, and create instances of Model B as needed. However, since the
lists of Model A are loaded through an external web service, and not
necessarily created until someone tries to create a Model B, we need
to go through Controller A’s create method as previously described.

“Ok,” I thought, “we’ll just let the Ajax request follow the
redirection.” Unfortunately, when redirected, Prototype (or Firefox,
I’m not sure which) doesn’t maintain those special headers that
indicate the request is from Ajax. So the response I got back was the
default HTML, complete with layout! So much for intuitive!

Then I thought, “Maybe the page.redirect_to method is the right
way.” No luck, that actually redirects the whole browser page since
it sends a window.location.href = "your url", which is exactly what
we don’t want.

In the end the solution I came up with was to create a new Ajax
request, like so:

However, I discovered that most of the delegated actions were really
just loading Model A from the session or parameters, and then
redirecting based on whether it was found and saved or not. Obviously
this pattern wouldn’t work for RJS/Ajax.

So I abstracted out the generated flash messages and redirection URLs
into hashes like so: