Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails 3: format.csv gives "no template error" but format.json needs no template

How come this works to render :json with no template, but not to render :csv?

in my datapoints_controller's index method:

respond_to do |format|
  format.json { render :json => @goal.datapoints.all }      
  format.csv { render :csv => @goal.datapoints.all }
end

Pointing my browser to /datapoints.json renders the collection as a json string on screen. Pointing it to /datapoints.csv gives an error:

Template Missing: with {:locale=>[:en, :en], :formats=>[:csv],
                         :handlers=>[:rhtml, :rxml, :erb, :builder, :rjs]}

An instance of Datapoint responds to to_csv, but even if I manually map it into csv format and render it as text it gives a Template Missing error, so, e.g. I tried something like this:

format.csv { render @goal.datapoints.map{|d| d.to_csv }.join "\n" }
like image 218
Bee Avatar asked Apr 30 '11 19:04

Bee


1 Answers

Rails comes with renderers for a bunch of formats, including json, but not csv. Here's where they are specified in the rails source (look towards the bottom for a series of add calls). It's pretty easy to create your own though.

Put something like this into an initialiser (this is pretty much just copied from the xml renderer from the above link, with xml replaced with csv):

ActionController::Renderers.add :csv do |csv, options|
  self.content_type ||= Mime::CSV
  self.response_body  = csv.respond_to?(:to_csv) ? csv.to_csv : csv
end

Then when you call render :csv => @foo this block will be called, with the @foo object passed as the csv parameter.

Looking at what your doing, you'll likely need to monkey patch Array to add a to_csv method, or make the above block detect and handle arrays.

like image 163
matt Avatar answered Nov 14 '22 23:11

matt