12

I've been reading similar questions, but many of the answers are outdated or not clear enough for me.

I'd like to be able to just do something like (in a controller action):

respond_to do |format|
  format.html
  format.csv
end

I know I'd then need a view such as action.csv.erb


So my questions are:

1) What do I need to configure in rails to allow this to happen in general.

2) How should I setup the CSV view to display some basic fields from a model?

UPDATE:

So I've tried to go the route of comma, I installed and vendored the gem.

Then according to the read me, I threw this into my model (customized to my needs):

comma do

user_id 'User'
created_at 'Date'
name 'Name'
end

I then threw this in the control for the index action (according to the readme):

  format.csv { render :csv => MyModel.limited(50) }

Then when accessing the index (not in CSV format) I receive the following ActionController Exception error:

undefined method `comma' for

So then I googled that, and I read that I should put require 'comma' in my model.

After doing that, I refreshed (my local index page), and the error changed to:

no such file to load -- comma

So at this point I decided it must not be finding the comma files obviously. So I copied the files from the vendored gem folder of comma, from comma's lib folder, to the rails lib folder. I then refreshed the page and landed on this error:

uninitialized constant Error

Then I pretty much gave up.

The errors from the trace were:

/Users/elliot/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:443:in load_missing_constant' /Users/elliot/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:80:in const_missing' /Users/elliot/.gem/ruby/1.8/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:92:in `const_missing'

Other notes, I have already installed FasterCSV

Hope thats enough info :)

4 Answers 4

11

I suggest taking a look at comma. It works very well and allows you to handle stuff at the model level, as opposed to the view level.

Sign up to request clarification or add additional context in comments.

4 Comments

I've been trying this with no success.
What didn't work out for you? If you are getting an error, could you update your original post with that error?
I can't seem to recreate your issue :/ I just started a new rails 2.3.5 project, installed comma as a gem, required it in my environment.rb file, unpacked the gem, created a dummy model with a call to comma and it works. Do you actually have a limited method on your model? If you try to just put the .csv format on the index and just pass it in every instance of your model, does it still not work?
Thanks for the continued effort, sometime yesterday I decided to give up on CSV for now and went a different route. Next time I come back to it I will certainly try this route (but from scratch)!
6

Have a look at FasterCSV.

csv_string = FasterCSV.generate do |csv|

  cols = ["column one", "column two", "column three"]

  csv << cols

  @entries.each do |entry|                
    csv << [entry.column_one, entry.column_two, entry.column_three ]
  end

  filename = "data-#{Time.now.to_date.to_s}.csv"    

end

send_data(csv_string, :type => 'text/csv; charset=utf-8; header=present', :filename => filename)  

3 Comments

So this would go in the controller? And then how would the file be accessed?
The send_data method returns the file to download by the user.
You need to put the send_data bit outside of the generate block. Also now that FasterCSV is incorporated into rails you just do CSV.generate.
4

This is terrible, but the CSV library (in 1.9, == FasterCSV) won't play nice with meta_where, so I did it this way:

@customers.collect {|c| lines.push ["#{c.lastname}","#{c.firstname}","#{c.id}","#{c.type}"}
lines = lines.collect {|line| line.join(',')}
csv_string = lines.join("\n")  
respond_to do |format|
  format.html
  format.csv { send_data(csv_string, :filename => "#{@plan.name.camelize}.csv", :type => "text/csv") }
end

It's ugly, but effective.

3 Comments

I like this answer, simple and effective if you're just generating a very basic CSV (although I moved the logic to the model instead of having it in the controller).
Yeah, this was a quick and dirty hack for me, but if you're going to use it "for real" the model is a much better place for it.
Just on a side note, if you think semantically - a model is terrible place for this. A customer shouldn't have knowledge of how to render itself. It's just not logical, besides fat models are too prominent in rails. Why not make a PORO which accepts the model and allows this method instead?
0

Take a look at CSV Shaper.

https://github.com/paulspringett/csv_shaper

It has a nice DSL and works really well with Rails models.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.