如何读取用户上传的文件,而不将其保存到数据库中

时间:2010-03-26 03:56:06

标签: ruby-on-rails xml ruby

我希望能够读取用户上传的XML文件(小于100kb),但不必先将该文件保存到数据库中。我不需要该文件超过当前操作(其内容被解析并添加到数据库;但是,解析文件不是问题)。由于可以使用以下方式读取本地文件:

File.read("export.opml")

我想过只为:uploaded_file创建一个file_field,然后尝试用

读取它
File.read(params[:uploaded_file])

但所有这一切都抛出一个TypeError(无法将HashWithIndifferentAccess转换为String)。我真的尝试了很多不同的东西(包括从/ tmp目录中读取),但是没有一个能够工作。

我希望我的问题简洁并不掩盖我试图自己解决这个问题所付出的努力,但我不想用一百种方法来污染这个问题,如何不完成它。非常感谢任何插话的人。

以下是我的观点:

<% 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 %>

我设置了一个自定义操作(上传),用于处理file_field上传,在提交后,将其传递给另一个自定义操作(解析)进行处理。这可能是我问题的一部分吗?

2 个答案:

答案 0 :(得分:46)

你非常接近。检查params[:uploaded_file]类类型,它通常应该是StringIOTempfile对象 - 这两个对象都已充当文件,并且可以是使用各自的read方法阅读。

只是为了确定(params[:uploaded_file]的班级类型可能会有所不同,具体取决于您使用的是Mongrel,Passenger,Webrick等)。您可以稍微进行一些详尽的尝试:

# 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

如果在您的情况下,params[:uploaded_file]是一个哈希值,请确保在调用file_field时没有错误地翻转object_namemethod个参数在您的视图中,或者您的服务器没有为您提供包含:content_type等密钥的哈希值(在这种情况下,请使用Bad file_data ... / {{development.log输出对此帖发表评论1}}。)

答案 1 :(得分:7)

我需要阅读yaml文件。我使用remotipart,这里是代码:

在html.slim

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

...

<input id="uploadInput" type="file" name="uploadInput">
控制器中的

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