简体   繁体   中英

Allowing User to Download Image from my S3 Bucket

I am trying to construct a method which will allow a user to download a pdf file from my s3 bucket, (which at the moment it does)

But some parts of the url may change from time to time, like the id number after /timetables, the filename (but will always be a pdf) and the id number after the filename

This is what i have so far

def download
  path = "images/timetables/14/original.pdf?"
  data = open("http://#{ENV['AWS_BUCKET']}.s3.amazonaws.com/#{path}/1392904333") 
  send_data data.read, filename: 'Timetable',
                       type: 'application/pdf', 
                       disposition: 'attachment', 
                       stream: 'true', 
                       buffer_size: '4096'

end

is there a way to get this information on the fly or can i only hardcode it? Ideally i want to store as much as the path into variables as i can.

Could anyone show me how to do this correctly please.

Thanks

It'll be easier to use paperclip to manage the uploading. Using this you'll create a table to save a record which will have a dynamic reference to your uploaded file on S3 .

The workflow goes like this:

  • You upload the PDF in question to your app
  • paperclip uploads it to S3 and saves the URL to your database
  • you provide a link to your users for the S3 URL of the PDF
  • OR you give them the link to your record and you initiate the download as you posted above

First the model which will hold the pdf file reference looks like this:

class PdfRecord < ActiveRecord::Base
  has_attached_file :pdf, :storage => :s3,
    :bucket => 'S3_BUCKET_NAME',
    :s3_credentials => {
      :access_key_id => 'AWS_ACCESS_KEY_ID',
      :secret_access_key => 'AWS_SECRET_ACCESS_KEY'
    }
end

Create a form for yourself to upload your pdf:

# app/views/pdf_records/new
<%= form_for @pdf_record, multipart: true do |f| %>
  <%= f.label :pdf %>
  <%= f.file_field :pdf %>
  <%= f.submit %>
<% end %>

Using this form you can upload the pdf and paperclip will save it to S3 and keep a reference to it in your database.

Give your users a link to your pdf_record like this:

@pdf_record = PdfRecord.find(which ever one you want)
@pdf_record.pdf.url # => the S3 url

Giving your users that url will let them download the pdf directly however, if you want to hide the URL and also allow you to update the pdf without breaking the link you can give the users a link to the pdf_record and then you initiate the download from your controller:

# give your users this url, as defined in your routes.rb
pdf_record_url(@pdf_record)

Then in the show action of the pdf_record controller:

def show
  pdf_record = PdfRecord.find(params[:id])
  data = open(pdf_record.pdf.url) 
  send_data data.read, filename: pdf_record.pdf_file_name,
                       type: pdf_record.pdf_content_type, 
                       disposition: 'attachment', 
                       stream: 'true', 
                       buffer_size: '4096'
end

Now, you can update that pdf_record whenever you want and since your users have a link to the record rather than the actual pdf file the link will always work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM