param被标识为字符串而不是文件

时间:2017-11-24 10:08:14

标签: ruby-on-rails forms file-io http-method

在我的视图文件submit.html.erb中,我决定直接使用<form>标记,而不是rails中包含的表单帮助程序。这是视图文件:

<form action = "/winter" method="post">
<input type="file" name="doc">
<p> Upload your question. </p>
<input type = "submit">
 <input name="authenticity_token" type="hidden" 
      value="....">
</form>

提交此表单会在/winters上使用参数

调用发布请求
{"doc"=>"1.docx", "authenticity_token"=>"...."}

虽然我希望doc参数是我上传的文件1.docx,但doc参数仍然是文件original_filename的字符串1.docx

我的routes.rb文件包含代码

post "/winter" => "paper#submit"

虽然在paper_controller的submit方法中是代码:

File.write("Papers/rain.docx", params[:doc].read)
redirect_to "/paper"

相应地,当我提交上述表格时,我会转到/winters网址并收到错误

  

未定义的方法&#39;阅读&#39; for&#34; 1.docx&#34;:String

那么为什么doc参数设置为文件名而不是文件本身?我认为这与文档相反:[http://guides.rubyonrails.org/form_helpers.html#what-gets-uploaded]

在这里可能相关的另一点是,在文档的第一段中,它说:

  

根据上传文件的大小,它实际上可能是一个StringIO或一个由临时文件支持的File实例。

那么,它是否说有时params[:doc]可能是文件实例,有时它可能是一个字符串?如何处理这种随机行为?

还有一件事,如果我尝试get请求而不是put请求怎么办? get必须将params放在url之后,作为查询字符串,对吗?那么params[:doc]应该始终是一个字符串吗?我尝试使用get,然后发送到网址

http://localhost:3000/winter?doc=1.docx

(我当时没有使用authenticity token params&#39;隐藏输入)。 当然,同样的

  

未定义的方法&#39;阅读&#39; for&#34; 1.docx&#34;:String

发生错误。

1 个答案:

答案 0 :(得分:1)

您必须使用multipart/formdata encoding才能使用文件传输。对于任何Web框架都是如此。

你也应该克服“waah学习很难”的事情,只需使用表单助手,因为它会添加正确的真实性标记:

<%= form_tag("/winter", multipart: true) do %>
  <%= file_field_tag 'doc' %>
  # ...
<% end %>
  

还有一件事,如果我尝试获取请求而不是put   请求? get必须将params放在url之后,作为查询   字符串,对吗?那么params [:doc]应该总是一个字符串吗?我试过了   使用get,并被发送到url

您无法在GET请求中上传文件。它们必须包含在具有multipart / formdata编码的POST / PATCH / PUT请求的请求主体中。