带文件输入字段的Rails表单 - 文件只是名称为字符串

时间:2018-02-15 08:12:18

标签: ruby-on-rails ruby forms input file-upload

我想在表单中嵌入一个文件输入字段。 但是在提交时,param值只是文件名,没有StringIO或其他任何东西,只是一个带文件名的字符串。

形式:

    <%= form_tag(controller: 'search', action: 'confirm_new_search', method: 'post', multipart: true) do %>
        [....]
        <div class="custom-file field" id="inc_form">
          <%= file_field :post, :file_inc_sellerslist, class: "custom-file-input" %>
          <label class="custom-file-label" for="file_inc_sellerslist">
            <%= t('dashboard.new_search.extra_search_options_entries.choose_file') %>
          </label>
        </div>
        [....]

那里有什么问题?

2 个答案:

答案 0 :(得分:2)

您的form_tag()语法不正确。 form_tag使用两个哈希作为参数:一个用于url,一个用于html属性。

  

form_tag(url_for_options = {},options = {},&amp; block)

     

启动一个表单标记,将操作指向配置了url_for_options的url,就像ActionController :: Base#url_for一样。方法   表单默认为POST。

     

选项

     

:multipart - 如果设置为true,则将enctype设置为   “多部分/格式数据”。

     

:方法 - 提交表单时使用的方法,通常是   “得到”或“发布”。如果使用“patch”,“put”,“delete”或其他动词,   添加名为_method的隐藏输入以模拟动词   交。

     

:authenticity_token - 在表单中使用的真实性令牌。仅限使用   如果您需要传递自定义真实性令牌字符串,或者不添加   完全是authenticity_token字段(通过传递false)。远程表单可能   通过设置省略嵌入的真实性标记   config.action_view.embed_authenticity_token_in_remote_forms = false。   当您对表单进行片段缓存时,这很有用。远程表格   从元标记中获取真实性标记,因此嵌入是   除非你支持没有JavaScript的浏览器,否则不必要。

     

:远程 - 如果设置为true,则允许使用Unobtrusive JavaScript   驱动程序来控制提交行为。默认情况下,此行为是   ajax提交。

     

:enforce_utf8 - 如果设置为false,则名称为utf8的隐藏输入不是   输出

     

任何其他键都会为代码创建标准HTML属性。

http://api.rubyonrails.org/v5.1/classes/ActionView/Helpers/FormTagHelper.html#method-i-form_tag

以下适用于我:

<%= form_tag({controller: 'search', action: 'confirm_new_search'},
  method: 'post', 
  multipart: true) do %>

以下是form_tag()调用的示例:

def go(x={}, y={})
  p x
  p y
end

go(a: 1, b:2, c:3)

--output:
{:a=>1, :b=>2, :c=>3}
{}

因此,您为form_for()指定的所有键/值对都会收集到散列中并分配给参数变量url_for_options。结果是你的form_tag()没有将html选项multipart设置为true。如果您查看html的源代码,您将看到:

<form action="/search/confirm_new_search?method=post&amp;multipart=true" 
      accept-charset="UTF-8" 
      method="post">

如果您将该html与form_tag()电话进行比较:

form_tag(controller: 'search', 
         action: 'confirm_new_search', 
         method: 'post', 
         multipart: true)

很明显,最后两个键/值对被添加到url中的查询字符串中。这种行为似乎没有在任何地方记录,但规则似乎是:对于url_for()无法识别的任何密钥,密钥和相应的值将添加到查询字符串中。并且,查询字符串中的键/值对与<form>标记的html属性无关。

答案 1 :(得分:0)

您也可以使用

form_tag({controller: 'search', action: 'confirm_new_search'}
, method: 'post', html: { multipart: true })

我遇到了同样的问题,并且对我有用