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
相关产品推荐
相关产品推荐

