Ruby on Rails export to csv - maintain mysql select statement order
Exporting some data from mysql to a csv file using FasterCSV. I'd like the columns in the outputted CSV to be in the same order as the select statement in my query.
Example:
rows = Data.find(
:all,
:select=>'name, age, height, weight'
)
headers = rows[0].attributes.keys
FasterCSV.generate do |csv|
csv << headers
rows.each do |r|
csv << r.attributes.values
end
end
CSV Output:
height,weight,name,age
74,212,bob,23
70,201,fred,24
.
.
.
I want the CSV columns in the same order as my select statement. Obviously the attributes method is not going to work. Any ideas on the best way to ensure that the columns in my csv file will be in the same order as the select statement? Got a lot of data and performance is a开发者_如何转开发n issue. The select statement is not static. I realize I could loop through column names within the rows.each loop but it seems kinda dirty.
Use the Comma gem:
class Data < ActiveRecord:Base
comma do
name
age
height
weight
end
comma :height_weight do
name
age
height_in_feet
weight
end
end
Now you can generate the CSV as follows:
Data.all(:select => 'name, age, height, weight').to_comma
Data.all(:select => 'name, age, height_in_feet, weight').to_comma(:height_weight)
Edit:
The ActiveRecord finders does not support calculated columns in the resultset, i.e.
data = Data.first(:select => 'name, age, height/12 as height_in_feet, weight')
data.height_in_feet # throws error
You can use select_extra_columns gem if you want to include the calculated columns.
Try this:
def export_to_csv (rows, col_names)
col_names = col_names.split(",") if col_names.is_a?(String)
FasterCSV.generate do |csv|
# header row
csv << col_names
# data rows
rows.each do |row|
csv << col_names.collect{|name| row.send(name)}
end
end
end
cols = 'name, age, height, weight'
rows = Data.find(:all, :select=> cols)
csv = export_to_csv(rows, cols)
精彩评论