ruby n max
ruby n max

Reputation: 97

How do I get this ruby on rails app to copy a file to my hard drive?

I have a file coming into my rails app from another website. The POST data looks like this:

Parameters: {"file"=>#<ActionDispatch::Http::UploadedFile:0x007fa03cf0c8d0 @original_filename="Georgia.svg", @content_type="application/octet-stream", @headers="Content-Disposition: form-data; name=\"file\"; filename=\"Georgia.svg\"\r\nContent-Type: application/octet-stream\r\n", @tempfile=#<File:/var/folders/g0/m3jlqvpd4cbc3khznvn5c_7m0000gn/T/RackMultipart20130507-52672-1sw119a>>, "originalFileName"=>"Georgia.ttf"}

My controller code is this:

def target     
  @incoming_file = params[:file]
  file_name = params[:originalFileName]
  File.open("/Users/my_home_directory/#{file_name}", "w+b") {|f| f.write(@thing)} 
end

Right now, I can create a file on my hard drive that contains a line of text that shows the object.

This is the code from the file created in my hard drive.

<ActionDispatch::Http::UploadedFile:0x007fa03cd1c318>

I can write a file with the name of the uploaded file. I can't seem to figure out how to write the data from the file to my drive. I'm new to ruby on rails. Help me see what I'm missing. Thx.

Upvotes: 3

Views: 6257

Answers (2)

VB.
VB.

Reputation: 484

Obvious solution would be the one suggested by Richie Min, but it is a bad solution in terms of memory usage, which might get critical if you start uploading large files. Since

File.open(...) {|f| f.write(@incoming_file.read)}

reads whole uploaded file in memory with @incoming_file.read. Better option would be:

def target
  @incoming_file = params[:file]
  file_name = params[:originalFileName]
  FileUtils.mv @incoming_file.tempfile, "/Users/my_home_directory/#{file_name}"
end

Uploaded data is always stored in temporary files, and UploadedFile.read is actually just a proxy to actual File object, which is accessible trough UploadedFile.tempfile. This, however, could also be not the best solution if temporary folder and destination directory are on different partitions or even on different disk drives, but still much better than reading the whole file in memory in Rails controller.

You can test it with:

curl -X POST -F file=@[some large file] -F originalFileName=somefilename.ext http://[your url]

Upvotes: 16

Richie Min
Richie Min

Reputation: 654

use

File.open("/Users/my_home_directory/#{file_name}", "w+b") {|f| f.write(@incoming_file.read)}

Upvotes: 1

Related Questions