You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 7多文件上传表单问题:如何提交所有上传文件而非仅最后一个

解决Rails 7多文件上传仅获取最后一个文件的问题

问题根源

你当前的代码里,每个文件输入框的name属性都是file,HTTP表单提交时同名参数会被最后一个值覆盖,所以控制器只能拿到最后一个上传文件。要接收多个文件,需要让文件输入框的name以数组形式命名(比如files[]),这样Rails会自动把所有上传文件收集到数组里。


步骤1:修改ERB视图,支持多文件提交

两种实现方式选其一即可:

方式一:直接指定数组格式的name(简洁版)

# 展示表格

<%= form_with url: kyc_document_upload_path, multipart: true do |f| %>
  <table>
    <% kyc_missing.each do |item| %>
      <tr>
        <td><%= item %></td>
        <td>
          <%# 用name: "files[]"让参数以数组形式提交 %>
          <%= f.file_field :files, name: "files[]" %>
        </td>
      </tr>
    <% end %>
  </table>
  <%= f.submit 'Submit', data: { turbo: false } %>
<% end %>

方式二:用fields_for带索引(更符合Rails表单规范)

# 展示表格

<%= form_with url: kyc_document_upload_path, multipart: true do |f| %>
  <table>
    <% kyc_missing.each_with_index do |item, index| %>
      <tr>
        <td><%= item %></td>
        <td>
          <%# 带索引的fields_for,生成的参数会是数组结构 %>
          <%= f.fields_for :files, index: index do |ff| %>
            <%= ff.file_field :file %>
          <% end %>
        </td>
      </tr>
    <% end %>
  </table>
  <%= f.submit 'Submit', data: { turbo: false } %>
<% end %>

步骤2:调整控制器代码,处理多文件转Base64

根据你选的视图方式,控制器代码略有不同:

对应方式一的控制器代码

# profile_controller.rb

class ProfileController < ApplicationController
  def kyc_document_upload
    # 遍历所有上传文件,逐个转为Base64字符串
    base64_documents = params[:files].map do |uploaded_file|
      Base64.encode64(uploaded_file.read)
    end

    # 如果需要和缺失文档类型对应(比如告诉外部服务哪个Base64对应哪个文档)
    # docs_with_types = kyc_missing.zip(base64_documents).map do |doc_type, base64|
    #   { document_type: doc_type, content: base64 }
    # end

    # 调用外部微服务,根据API要求传入参数
    ExternalApi.user.sent_missing_docs(base64_documents)
    
    redirect_to profile_path, notice: '所有文件已成功提交'
  end
end

对应方式二的控制器代码

(因为fields_for生成的参数是params[:files]数组,每个元素是包含:file键的哈希)

# profile_controller.rb

class ProfileController < ApplicationController
  def kyc_document_upload
    base64_documents = params[:files].map do |file_hash|
      uploaded_file = file_hash[:file]
      # 跳过未上传的文件
      next unless uploaded_file.present?
      Base64.encode64(uploaded_file.read)
    end.compact # 移除nil值(未上传的项)

    ExternalApi.user.sent_missing_docs(base64_documents)
    
    redirect_to profile_path, notice: '所有文件已成功提交'
  end
end

内容的提问来源于stack exchange,提问作者mr_muscle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 07:35:21