4

I'm giving user opportunity to upload their files. However, application is not saving those files into the database, it only needs to get informations out of it.

So from a form which looks like this:

= simple_form_for @channel, method: :post do |f|
    = f.input :name
    = f.input :configuration_file, as: :file
    = f.submit

come params[:channel][:configuration_file]

#<ActionDispatch::Http::UploadedFile:0xc2af27c @original_filename="485.csv", @content_type="text/csv", @headers="Content-Disposition: form-data; name=\"channel[configuration_file]\"; filename=\"485.csv\"\r\nContent-Type: text/csv\r\n", @tempfile=#<File:/tmp/RackMultipart20140822-6972-19sqxq2>>

How exactly can i read from this thing? I tried simply

File.open(params[:channel][:configuration_file])

but it returns error

!! #<TypeError: can't convert ActionDispatch::Http::UploadedFile into String>

PS Additional solutions for xml and csv would be much appreciated!

Leo
  • 2,061
  • 4
  • 30
  • 58

2 Answers2

3

According to the Rails docs:

http://api.rubyonrails.org/classes/ActionDispatch/Http/UploadedFile.html

an uploaded file supports the following instance methods, among others:

open() 

path()

read(length=nil, buffer=nil) 

you could try:

my_data = params[:channel][:configuration_file].read

to get a string of the file contents?

or even:

my_data = File.read params[:channel][:configuration_file].path

Also, if the file can be long, you may want to open the file and read line by line. A few solutions here:

How to read lines of a file in Ruby

If you want to read a CSV file, you could try:

require 'csv'    

CSV.foreach(params[:channel][:configuration_file].path, :headers => true) do |row|
  row_hash = row.to_hash
  # Do something with the CSV data
end

Assuming you have headers in your CSV of course.

For XML I recommend the excellent Nokogiri gem:

http://nokogiri.org/

At least partly because it uses an efficient C library for navigating the XML. (This can be a problem if you're using JRuby). Its use is probably out of scope of this answer and adequately explained in the Nokogiri docs.

Community
  • 1
  • 1
A Fader Darkly
  • 3,516
  • 1
  • 22
  • 28
1

From the documentation

The actual file is accessible via the tempfile accessor, though some of its interface is available directly for convenience.

You can change your code to:

file_content = params[:channel][:configuration_file].read

or if you want to use the File API:

file_content = File.read params[:channel][:configuration_file].path
Paulo Fidalgo
  • 21,709
  • 7
  • 99
  • 115