如何将选定的文件名传递给控制器以在 Rails 中进行处理
How to pass selected filename to controller to process in Rails
我想 select 本地计算机上的一个 zip 文件并在添加到数据库之前对其进行处理。
除了传入文件名外,我已经让控制器完成所有这些工作。如果我手动输入文件名就可以了。
<%= form_with model: @bp, url: { action: "import_data" } do |form| %>
<%= form.file_field :health_exported_zip %>
<%= submit_tag( "Import" ) %>
<% end %>
bp_controller
def import_data
# Following line errors
health_exported_zip_file = params[:health_exported_zip] # no implicit conversion of nil into String
# Manually setting file location which works with the above line commented out
health_exported_zip_file = "/Users/username/Downloads/export.zip"
unzip_import_data(health_exported_zip_file)
…
end
def unzip_import_data(health_exported_zip_file)
require 'zip'
unzip_to = "import_staging"
…
end
# Only allow a list of trusted parameters through.
def bp_params
params.require(:bp).permit(:statdate, :systolic, :diastolic, :heartrate, :sourceName, :sourceVersion, :comment, :health_exported_zip)
end
这个做起来一定很简单,但是我很茫然。使用类似 form_with
的 ActiveStorage 在文件上传时必须有权访问该文件。谢谢
如此不简单,但@masasakano 指出我阅读了 params
,我按如下方式解析它以获取 zip 文件的临时副本的路径。
indexTempfile = params.to_s.index('/var/folders') # setting start of Tempfile location
tempfile_path = params.to_s.slice!(indexTempfile..450) # slice off the beginning of params
indexEnd = tempfile_path.to_s.index('>') - 1 # get end of Tempfile location.
tempfile_path = tempfile_path.to_s.slice!(0..indexEnd) # slice off the end of params and left with path
tempfile_path
是 health_exported_zip_file
所需要的。已重命名,因为它不是原始文件。
什么 params
returns 是一个 ActionDispatch::Http::UploadedFile object (see Official reference)。因此 params
的 returned 值是 而不是 您用 unzip_import_data(health_exported_zip_file)
.
手动设置的文件名
相反,您可以使用 params[:bp][:health_exported_zip].path
(params[:bp][:health_exported_zip].tempfile.path
的别名)获取上传文件的路径,您可以将其提供给解压缩功能。
所以,这是我注意到的一个问题。
但是,如果您遇到的异常是no implicit conversion of nil into String
,那么我猜params
首先未能提取上传的文件,然后params[:bp][:health_exported_zip]
returns nil
。有很多潜在的原因,例如,您实际上没有上传文件(即使您认为您上传了),或者上传的文件超过了最大允许大小,或者没有从视图调用控制器如您所愿,等等……
我的建议是在您的特定情况下转储 params
以查看传递给您的控制器的内容作为您调查的起点。
[编辑]
交换意见后发现,Controller中包含的OP的预过滤方法是not在OP的测试用例中调用的。然后,由于 Rail 的强参数约束,health_exported_zip
从 params
中过滤掉,params[:bp][:health_exported_zip]
将 return nil
。因此,您应该在 before_action
的 only
子句中添加 :import_data
以调用预处理方法。或者,更直接的方法是在 import_data
方法的开头添加您选择的 params.permit
等行。
我想 select 本地计算机上的一个 zip 文件并在添加到数据库之前对其进行处理。
除了传入文件名外,我已经让控制器完成所有这些工作。如果我手动输入文件名就可以了。
<%= form_with model: @bp, url: { action: "import_data" } do |form| %>
<%= form.file_field :health_exported_zip %>
<%= submit_tag( "Import" ) %>
<% end %>
bp_controller
def import_data
# Following line errors
health_exported_zip_file = params[:health_exported_zip] # no implicit conversion of nil into String
# Manually setting file location which works with the above line commented out
health_exported_zip_file = "/Users/username/Downloads/export.zip"
unzip_import_data(health_exported_zip_file)
…
end
def unzip_import_data(health_exported_zip_file)
require 'zip'
unzip_to = "import_staging"
…
end
# Only allow a list of trusted parameters through.
def bp_params
params.require(:bp).permit(:statdate, :systolic, :diastolic, :heartrate, :sourceName, :sourceVersion, :comment, :health_exported_zip)
end
这个做起来一定很简单,但是我很茫然。使用类似 form_with
的 ActiveStorage 在文件上传时必须有权访问该文件。谢谢
如此不简单,但@masasakano 指出我阅读了 params
,我按如下方式解析它以获取 zip 文件的临时副本的路径。
indexTempfile = params.to_s.index('/var/folders') # setting start of Tempfile location
tempfile_path = params.to_s.slice!(indexTempfile..450) # slice off the beginning of params
indexEnd = tempfile_path.to_s.index('>') - 1 # get end of Tempfile location.
tempfile_path = tempfile_path.to_s.slice!(0..indexEnd) # slice off the end of params and left with path
tempfile_path
是 health_exported_zip_file
所需要的。已重命名,因为它不是原始文件。
什么 params
returns 是一个 ActionDispatch::Http::UploadedFile object (see Official reference)。因此 params
的 returned 值是 而不是 您用 unzip_import_data(health_exported_zip_file)
.
相反,您可以使用 params[:bp][:health_exported_zip].path
(params[:bp][:health_exported_zip].tempfile.path
的别名)获取上传文件的路径,您可以将其提供给解压缩功能。
所以,这是我注意到的一个问题。
但是,如果您遇到的异常是no implicit conversion of nil into String
,那么我猜params
首先未能提取上传的文件,然后params[:bp][:health_exported_zip]
returns nil
。有很多潜在的原因,例如,您实际上没有上传文件(即使您认为您上传了),或者上传的文件超过了最大允许大小,或者没有从视图调用控制器如您所愿,等等……
我的建议是在您的特定情况下转储 params
以查看传递给您的控制器的内容作为您调查的起点。
[编辑]
交换意见后发现,Controller中包含的OP的预过滤方法是not在OP的测试用例中调用的。然后,由于 Rail 的强参数约束,health_exported_zip
从 params
中过滤掉,params[:bp][:health_exported_zip]
将 return nil
。因此,您应该在 before_action
的 only
子句中添加 :import_data
以调用预处理方法。或者,更直接的方法是在 import_data
方法的开头添加您选择的 params.permit
等行。