Forum: Ruby on Rails dynamically generated CSV files

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
E25296bf52723dc37bc462271eb02d2d?d=identicon&s=25 Jason Pfeifer (jpfeifer)
on 2009-01-10 01:44
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
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2009-01-10 03:06
(Received via mailing list)
Jason Pfeifer 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
E25296bf52723dc37bc462271eb02d2d?d=identicon&s=25 Jason Pfeifer (jpfeifer)
on 2009-01-10 03:52
>    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
E25296bf52723dc37bc462271eb02d2d?d=identicon&s=25 Jason Pfeifer (jpfeifer)
on 2009-01-10 03:56
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
C64e63b70be7dfed8b0742540b8b27e5?d=identicon&s=25 Mark Reginald James (Guest)
on 2009-01-10 04:52
(Received via mailing list)
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.

--
Rails Wheels - Find Plugins, List & Sell Plugins -
http://railswheels.com
This topic is locked and can not be replied to.