views:

225

answers:

1

Wanting to play with jQuery, Orbited, and FasterCSV, I made a Rails chat application.

You can browse to a URL and there is a chat window that is similar to IRC. You can also export the contents of the chat window by visiting the same URL but adding a ".csv" extension to the URL.

HTML version: http://host.name/channel/sweetchatroom

CSV version: http://host.name/channel/sweetchatroom.csv

In Firefox, Safari, and Chrome it works normal. In IE, If I visit the "HTML" URL, I get the CSV version of the page. I have to manually add ".html" to the URL like so:

http://host.name/channel/sweetchatroom.html

My route currently looks like this:

map.chat '/channel/:name.:format', :controller => 'channels', :action => 'show'

I Googled a bit and tried the following suggestions:

map.slug '/channel/:slug.:format', :controller => 'channels', :action => 'show', :defaults => {:format => 'html'}

-- and --

map.slug '/channel/:slug.:format', :controller => 'channels', :action => 'show', :format => 'html'

Neither of them worked. Apparently, if you visit a URL without specifying the format, Rails does not set params[:format] to anything. Which in principle I prefer, but the docs are pretty clear that you can set a default format and I'm not sure why it doesn't honor this. The ":defaults => ..." suggestion is what is in the Rails docs.

In order to get it to work I had to change this part of my channels controller:

respond_to do |format|
  format.csv { 
    send_data channel_to_csv(@channel),
      :type => "text/plain",
      :filename => "#{@channel.slug}.csv",
      :disposition => 'inline'
  } 
  format.html # show.html.erb
  format.xml  { render :xml => @channel }
end

To this:

respond_to do |format|
  format.csv { 
    send_data channel_to_csv(@channel),
      :type => "text/plain",
      :filename => "#{@channel.slug}.csv",
      :disposition => 'inline'
  } if params[:format] == 'csv' # <-- Here is the change
  format.html # show.html.erb
  format.xml  { render :xml => @channel }
end

It works perfectly but seems really hackish. There has to be a better, more "Ruby" way. Do I have the syntax wrong on my routes entry? It seems like routes is where this should be.

I know I have to be missing something. I couldn't find good information on this problem on Google or on StackOverflow. That generally means I'm way out in the weeds.

+2  A: 

I usually just put the format.html first. That way, when IE sends a weird accepts header (like */*), it doesn't get fouled up. Basically, if IE says it accepts everything (like when there is no extension on the URL) Rails will send it the first thing that matches.

MattMcKnight
That was one of the things I had considered and for whatever reason I had not tried it.
hernan43
+1 for using "wonky" in your title. This is the rails 2.0 IE Accepts header issue. Google for "rails ie accepts".
Jonathan Julian