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?
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
.)
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With