1

I have a method called "revisions", and I want to be able use the same logic but output to csv. I think I'd like to use the FasterCSV gem. What I need is to what to add to my routes in order to get a route for both the html and the csv outputs. I'd like my urls to be something like this:

invoices/51/revisions
invoices/51/revisions.csv

Thoughts?

Thanks much!

yfeldblum
  • 65,165
  • 12
  • 129
  • 169
Mr Mikkél
  • 2,577
  • 4
  • 34
  • 52

2 Answers2

2

Rails makes this very easy. You don't need to change your routes at all to accommodate CSV format, since rails recognizes the csv MIME-type.

First, set up a route in routes.rb:

map.invoice_revisions 'invoices/:id/revisions.:format', 
                      :controller=>:invoices, 
                      :action=>:revisions 

In your controller, do something like this:

def revisions
  # ... set @revisions with something like
  @revisions = Invoice.find(params[:id]).revisions

  respond_to do |format|
    format.html # will render the revisions html template
    format.csv { render :csv => revisions_csv } # see sample method below
    end
  end
end

private
  def revisions_csv # convert @revisions to csv: customize to your needs
    FasterCSV.generate do |csv|
      csv << @revisions.first.attributes.keys  # set the headers
      @revisions.each do |revision|            # set the data
        csv << revision.attributes.values
      end
    end
  end

Here's a tutorial with more detailed info on formatting the csv files using csvbuilder:

http://rubyglasses.blogspot.com/2009/07/csv-views-with-fastercsv-and-csvbuilder.html

bowsersenior
  • 12,524
  • 2
  • 46
  • 52
  • Even with the respond_to in there, I am getting: Couldn't find WorkOrder with ID=revisions – Mr Mikkél Nov 28 '10 at 08:17
  • Look again at the updated answer. I added some info on setting up your routes. I assumed you already had a route set up for the html version of the view. – bowsersenior Nov 28 '10 at 08:42
  • oops... here's the route: map.invoice_revision 'invoices/:id/revisions', :controller=>:invoices, :action=>:revisions ... along with this one before it: map.resources :invoices, :collection=>{:browse=>:get}, :member=>{:select=>:post} – Mr Mikkél Dec 03 '10 at 17:25
  • OK, the routes I had in my answer were not quite right. What you are missing in your routes is `.:format` at the end to capture the `.csv` . I also updated my answer to look for `:id` instead of `:invoice_id` . Please see the updated answer and check if it works. – bowsersenior Dec 03 '10 at 21:13
  • (Sorry, I would have checked/responded sooner if stackoverflow were to email me when I got these responses!) ... now on to figuring out the csv part. THANK YOU! – Mr Mikkél Dec 11 '10 at 16:35
  • Glad you got it working. The CSV part should be relatively easy. – bowsersenior Dec 11 '10 at 18:39
  • Turns out it was. Thanks again :) – Mr Mikkél Dec 12 '10 at 04:41
0

In your routes.rb:

resources :photos do
  get 'preview', :on => :member
end

http://guides.rubyonrails.org/routing.html#adding-more-restful-actions

And in your controller, handle the format with a respond_to.

Kalyan Maddu
  • 4,123
  • 2
  • 21
  • 26