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

Goo*_*ets 42 ruby xml ruby-on-rails

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

File.read("export.opml")
Run Code Online (Sandbox Code Playgroud)

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

File.read(params[:uploaded_file])
Run Code Online (Sandbox Code Playgroud)

但所有这一切都是抛出一个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 %>
Run Code Online (Sandbox Code Playgroud)

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

vla*_*adr 47

你很近.检查类型params[:uploaded_file],它通常应该是A 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
Run Code Online (Sandbox Code Playgroud)

如果,在您的情况下,事实证明这params[:uploaded_file]是一个哈希,请确保您在视图中调用时没有错误地翻转object_namemethod参数file_field,或者您的服务器没有给您带有:content_type等等键的哈希值(在这种情况下)请用/ 的Bad file_data ...输出评论这篇文章.)development.logproduction.log


小智 8

我需要阅读yaml文件.我使用remotipart和这里的代码:

在html.slim中

 =form_tag('/locations/check_for_import', method: :post, remote: true, multipart: true)
Run Code Online (Sandbox Code Playgroud)

...

<input id="uploadInput" type="file" name="uploadInput">
Run Code Online (Sandbox Code Playgroud)

在控制器中

content = File.read(params[:uploadInput].tempfile)
doc = YAML.load(content)
Run Code Online (Sandbox Code Playgroud)