dynamically generated CSV files

Jason Pfeifer wrote:

Greetings, I have a method from which I want to generate CSV files based on the model name:

def export_table_to_csv(table)

  require 'csv'

  @table = table   @results = @table.find(:all)   @titles = @table.column_names

  report = StringIO.new   CSV::Writer.generate(report, ',') do |title|     title << @titles     @results.each do |result|       title << result.attributes.values     end   end

  report.rewind   file = File.open("#{RAILS_ROOT}/the_directory/#{@table}.csv", "wb")   file.write(report.read)

end

The above script works fine right now, however the call to result.attributes.values returns them in a different order than @table.column_names, so that the values end up in the wrong places. ie. the name will be under the email column etc.

any thoughts on how I can make it spit out in the order it's in from the database?

Replace title << result.attributes.values with

   title << @titles.map { |a| result.send(a) }

And, for anyone needing the code to dump any database table to a CSV file, here is the refactored, much tidier code using fastercsv

def table2CSV(table)   require 'fastercsv'

  @table = table   @titles = @table.column_names

  @users = @table.find(:all)   FasterCSV.open("#{RAILS_ROOT}/csv_directory/#{@table}.csv", "wb") do

csv>

    csv << @titles     @users.each do |user|         csv << @titles.map { |a| user.send(a) }     end   end

end

Jason Pfeifer wrote:

So if I have that correct, I don't understand how the send method operates on the result object. Is it just passing a method name? I guess I was just mistakenly thinking of it in terms of key value pairing:

result.send(a) AS result[a]

result.send(a) just calls the method with name a on the result object.

result[a] would also be acceptable, accessing the attribute directly, but failing if you've written a custom accessor method for that attribute.