Routing problems for different formats

I am having 2 similar problems with routing.

  1. With Rails if I make a js request using jQuery I always have to
    append a “.js” extension to allow the request to be handled
    appropriately. If I don’t append a js extension I get html formatted
    data back. Using Merb this never happened and worked like I thought it
    should.

  2. Today I am having problems allowing xml requests to be handled by the
    controller. Even if I have a respond_to block that accepts xml
    requests, the html block will handle it instead. If I try the work
    around mentioned in problem #1 Rails throws an error of being unable to
    route the request. If I add a :format key to the specific route in the
    routes.rb file, that defaults to :html, it then works.

Why is it that I have to allow for the :format in the xml case, but in
the :js case I need the .js extension?

Am I missing something? This seems a little too sloppy for Rails.

Without looking at your routes and code it’s really had to find a
reason.

Maurício Linhares
http://codeshooter.wordpress.com/ | http://twitter.com/mauriciojr

On Sun, Aug 23, 2009 at 6:01 PM, Chris

Maurício Linhares wrote:

Without looking at your routes and code it’s really had to find a
reason.

A big part of the issue is that the initial problems are using standard
code, the hacks only come into play to make things work.

First issue:
$(“#terms-of-use”).click(function() {
var url = this.href + “.js” // <= hack #1 to allow format.js block to
be called
$.get(url, function() {

})
})

controller

def terms_of_use
respond_to do |format|
format.html {}
format.js {render :action => “terms_of_use”, :layout => false}
end
end

Second issue
Enter http://foobar.com/schedule/1.xml into browser

#controller
def schedule
@todos = User.find(params[:id]).todos
respond_to do |format|
format.html {}
format.xml { render :xml => @todos.to_xml }
end
end

routes.rb

this won’t work to allow the xml request to be made

map.schedule “schedule/:id”, :controller => “main”, :action =>
“schedule”

Hack #2: adding the format option will allow it to work

map.schedule “schedule/id.:format”, :controller => “main”, :action =>
“schedule”, :format => “html”

Thanks for clearing that up Maurício.

Hi Chris,

You’re not doing any hacks, you’re doing what’s expected to tell rails
that a route will accept various formats, you should take a look at
the routes guides to undertand how the respond_to method works.

Also, to get JQuery to behave correctly without the “.js” you’ll need
to add this somewhere in your application.js:

$(document).ready(function () {

jQuery.ajaxSetup({
    'beforeSend': function(xhr) {
        xhr.setRequestHeader("Accept", "text/javascript")
};

});

On the routes issue, as I said before, that’s how it works. A route
like:

map.schedule “schedule/:id”, :controller => “main”, :action =>
“schedule”

Will never call the respond_to with XML as a format unless the client
sends an “Accept: application/xml” as a header and I think you’re not
doing this, so, the route with a explicit format is required, this is
no bug, that’s exactly how it should behave. Also, avoid mapping URLs
directly as you’re doing, these paths should be mapped using
resources.

Maurício Linhares
http://codeshooter.wordpress.com/ | http://twitter.com/mauriciojr

On Sun, Aug 23, 2009 at 6:53 PM, Chris