I want to select a zip file on local computer and process it before adding to database.
I've got the controller working to do all of this except pass in the filename. It works if I put in the filename manually.
<%= 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
This must be simple to do, but I'm at a loss. ActiveStorage using similar form_with
must have access to the file when file uploading. Thank you
So not simple, but @masasakano pointed me to reading params
which I parsed as follows to get path to the temporary copy of the zip file.
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
is what need as health_exported_zip_file
. Renamed since it's not the original file.
What params
returns is an ActionDispatch::Http::UploadedFile object (see Official reference). So the returned value of params
is not the filename as you manually set with unzip_import_data(health_exported_zip_file)
.
Instead you can use params[:bp][:health_exported_zip].path
(which is an alias of params[:bp][:health_exported_zip].tempfile.path
) to get the path of the uploaded file, which you can feed to your unzip function.
So, that is a problem I have noticed.
However, if the exception you encounter is no implicit conversion of nil into String
as you state, then I guess params
has failed to pick up the uploaded file in the first place and then params[:bp][:health_exported_zip]
returns nil
. There are numerous potential causes for it, such as, you actually didn't uploaded a file in your attempt (even though you think you did), or the uploaded file exceeded the maximum permitted size, or the controller is not called from the view as you intend, etc…
My advice is to dump params
in your particular case to see what is passed to your controller as a starting point of your investigation.
[Edit]
After exchanging comments, it turned out the pre-filtering method the OP included in the Controller is not called in the OP's test case. Then, health_exported_zip
is filtered out from params
because of Rail's strong parameter constraint, and params[:bp][:health_exported_zip]
would return nil
. So, you should add :import_data
in the only
clause in your before_action
to call the pre-handing method. Alternatively, a more direct way is to add the line of your chosen params.permit
etc at the head of the import_data
method.