Gracefully degrading Ajax AND Drying up actions

Still a semi-newbie, but so far I’ve managed to solve most things with a
bit of help from the Agile book, some googling around, and a bit of
trial-and-error, but I’m really stuck with this one (very much an Ajax
newbie):

I know how to gracefully degrade an AJAX newpost type call so it can
appear inline or (for those without JS support) go to a new page (put an
“:href => url_for” in the link_to_remote).

I also know how to DRY up two (non-AJAX) actions so that you use the
same newpost for both the original call and processing the form info (if
request.get? … elsif request.post?).

I even know how to have it so the same newpost action can handle the
original request and tell if it’s an AJAX request or not, so I can use
just one action for AJAX and none AJAX requests
(request…xml_http_request?).

What I can’t work out to do is how to have it so the processing of the
AJAX a form info is done in the same action as the original AJAX call
(they are both posts, right?), and it’s forcing me to have a createpost
action, just for the AJAX route.

If I could work this out, I could then have one neat action that wrapped
the whole thing up in a nice DRY, gracefully degrading way.

Can anyone help?

Thanks
Chris T

On Apr 1, 2006, at 5:34 AM, Chris T wrote:

the same newpost for both the original call and processing the form
have a createpost action, just for the AJAX route.
Are you testing request.xhr? before you test for request.post?

If not, switch them around (or say “request.post? && ! request.xhr?”)
since all xhr? posts are, of course, posts!

-Rob

Rob B. http://agileconsultingllc.com
[email protected]

Rob B. wrote:

the AJAX a form info is done in the same action as the original AJAX
Rob B. http://agileconsultingllc.com
[email protected]

The problem is not differentiating between the non-xhr posts and xhr
posts (the order I’ve got it currently is: test for gets, else test for
xhr, else test for post, which I think has the same effect) but
testing between the xhr posts that are the original call (i.e. the
equivalent of the non-Ajax GET) and those that are returning form
values.

I suspect I’m being dense here, but can’t figure it out. It’s simple if
I have a new post and create post action – then on each I only need to
test xhr? – and this avoids duplicating the codes for xhr and non-xhr,
but does mean two actions. Not the end of the world, but would be nice
to know if it’s easy to do (and therefore I am being dense).

Cheers
Chris

Solved this – of a fashion, though the code is somewhat ugly at the
moment so I’m not convinced I’m doing it the best way:

def newpost # NB somewhat simplified to remove some of the non-logic
bits
if request.get? # tests if non-Ajax GET request in which case…
… # generate new object
return
elsif request.xml_http_request? # tests if Ajax request
if not params[:post] # could prob bundle this up in Ajax test
above
… # generate new object for Ajax calls
end
end
@post=Post.new(params[:post]) #get the params, whether they came from
Ajax or non-Ajax call
if @post.save
flash[:notice] = “New post submitted successfully”
if not request.xml_http_request? # plain old vanilla non-Ajax
redirect_to :action => ‘index’ and return
else
render(:partial => ‘post’, :object => @post, :layout =>
false) # show the new item for Ajax
end
elsif request.xml_http_request? # if we haven’t saved successfully
and it was an Ajax call
render :action => ‘newpost’, :id => params[:id], :layout => false
and return # re-show form
else
render :action => ‘newpost’, :id => params[:id] and return # ditto
for non-Ajax call
end
end

Comments or suggestions for improving this?
Thanks
Chris T