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?
Cheers,
Jason
Jason P. wrote:
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) }
–
Rails Wheels - Find Plugins, List & Sell Plugins -
http://railswheels.com
title << @titles.map { |a| result.send(a) }
thanks! That’s working great. Would you care to explain for me how
that works? When I read the code, I think this:
@titles.map iterates over each item in the titles array, so if I were
just to do:
@titles = [1, 4, 6, 8]
@titles.map { |a| a + 2 }
=> [3, 6, 8, 10]
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]
Thanks.
Jason
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 P. 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.
–
Rails Wheels - Find Plugins, List & Sell Plugins -
http://railswheels.com