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.