how to read a User uploaded file, without saving it to the database

Ruby on-RailsXmlRuby

Ruby on-Rails Problem Overview


I'd like to be able to read an XML file uploaded by the user (less than 100kb), but not have to first save that file to the database. I don't need that file past the current action (its contents get parsed and added to the database; however, parsing the file is not the problem). Since local files can be read with:

File.read("export.opml")

I thought about just creating a file_field for :uploaded_file, then trying to read it with

File.read(params[:uploaded_file])

but all that does is throw a TypeError (can't convert HashWithIndifferentAccess into String). I really have tried a lot of various things (including reading from the /tmp directory as well), but could get none of them to work.

I hope the brevity of my question doesn't mask the effort I've given to try to solve this on my own, but I didn't want to pollute this question with a hundred ways of how NOT to get it done. Big thanks to anyone who chimes in.

Here is my view:

<% form_for(:uploaded_file, @feed, :url => {:action=>'parse'}, :html=> {:multipart=>true}) do |f| %>  <p>
  	<%= f.label :uploaded_file, 'Upload your file.' %><br />
  	<%= f.file_field :uploaded_file %>
  </p>
  <p><%= f.submit 'upload' %></p>
<% end %>

I set up a custom action (upload) which handles the file_field upload, which after submission, is passed off to another custom action (parse) for processing. Could this be a part of my problem?

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

You are very close. Check the class type of params[:uploaded_file], it should typically be either a StringIO or a Tempfile object -- both of which already act as files, and can be read using their respective read method(s).

Just to be sure (the class type of params[:uploaded_file] may vary depending on whether you are using Mongrel, Passenger, Webrick etc.) you can do a slightly more exhaustive attempt:

# Note: use form validation to ensure that
#  params[:uploaded_file] is not null

file_data = params[:uploaded_file]
if file_data.respond_to?(:read)
  xml_contents = file_data.read
elsif file_data.respond_to?(:path)
  xml_contents = File.read(file_data.path)
else
  logger.error "Bad file_data: #{file_data.class.name}: #{file_data.inspect}"
end

If, in your case, it turns out that params[:uploaded_file] is a hash, make sure that you have not mistakingly flipped the object_name and method parameters when invoking file_field in your view, or that your server is not giving you a hash with keys like :content_type etc. (in which case please comment on this post with the Bad file_data ... output from development.log/production.log.)

Solution 2 - Ruby on-Rails

I need to read yaml files. I use remotipart and here the code:

in html.slim

 =form_tag('/locations/check_for_import', method: :post, remote: true, multipart: true)

...

<input id="uploadInput" type="file" name="uploadInput">

in controller

content = File.read(params[:uploadInput].tempfile)
doc = YAML.load(content)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGoodGetsView Question on Stackoverflow
Solution 1 - Ruby on-RailsvladrView Answer on Stackoverflow
Solution 2 - Ruby on-RailsIvanView Answer on Stackoverflow