Home Rails file download using send_data with follow-up action
Reply: 0

Rails file download using send_data with follow-up action

user2896
1#
user2896 Published in May 27, 2018, 3:38 am

I am working on a code base where I need to allow the user to download a PDF document that already resides on AWS S3. I have implemented a download concern that was used for a previous feature.

For this feature, I need to update the UI (A progress stepper) after the user has completed the file download. I was initially thinking that this would be as simple as:

  1. User clicks download
  2. API call is made where the file is downloaded using send_data. In this API call, I'd also update the Foo model to change state to indicate that the user has downloaded the file;
  3. Execute a redirect_to request.referer to reload the data. The changed state in Foo will be responsible for showing the updated progress in the UI;

I was mistakenly thinking that this was going to be simple. The reasons for complexity:

  1. send_data is already rendering data, so I can't refresh the page using redirect_to as this triggers a multiple render error;
  2. send_data does not work with the remote: true option, so requesting data via an AJAX link and updating the ERB template is out;
  3. I can write everything into a JS on click function, but this seems like a bit of a hack. I probably need to retrieve the file directly from AWS and skip my api? I'm suspecting that I might run into CORS issues as I don't have control over the server.

This is what my rails download method looks like currently:

def download
  attachment = Attachment.find_by_id(params[:attachment_id])
  content = send_data(
    attachment.file.read,
    filename: "#{attachment.title}.#{attachment.file.file.extension}",
    type: attachment.content_type,
    disposition: "attachment",
  )
end

Th js code that basically worked looks like this where all the relevant paths & filenames are passed on to the JS via data-attributes:

$(document).on("click", "#download", function(e){
  e.preventDefault();
  const data = $('#temp-information').data();
  var req = new XMLHttpRequest();
  req.open("GET", data.path, true);
  req.responseType = "blob";
  const filename = data.title;
  req.onload = function (event) {
    var blob = req.response;
    console.log(blob.size);
    var link=document.createElement('a');
    link.href=window.URL.createObjectURL(blob);
    link.download= filename;
    document.body.appendChild(link);
    link.click();
  };
  if (typeof window.navigator.msSaveBlob !== 'undefined') {
    // Fix to work in IE11
    window.navigator.msSaveBlob(blob, filename);
  } else {
    req.send();
  }
});

What is the most effective & rails'y way of handling a file download & updating the UI after the download has been completed?

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.305678 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO