Currently users can download an ActiveStorage blob in my app using the following link:
link_to 'download', rails_blob_path(pj.document.file, disposition: 'attachment')
However, I would like to update an attribute in the database for the associated model to register when the file was first downloaded. This field is called the downloaded_at field.
I have made the following attempt:
Added the following code in the database:
def download
@proofreading_job = ProofreadingJob.find(params[:id])
@proofreading_job.update(downloaded_at: Time.current) if current_user == @proofreading_job.proofreader.user
response.headers["Content-Type"] = @proofreading_job.document.file.content_type
response.headers["Content-Disposition"] = "attachment; #{@proofreading_job.document.file.filename.parameters}"
@proofreading_job.document.file.download do |chunk|
response.stream.write(chunk)
end
ensure
response.stream.close
end
However, this does not do anything except redirect to the @proofreading_job page which is not what I want.
Has anyone done this before and if so how can I accomplish this task.
In the end I just used some javascript to capture the click of the button as follows:
td = link_to rails_blob_path(pj.document.file, disposition: 'attachment'),
id: pj.document.id,
download: pj.document.file_name,
class: "btn btn-outline-secondary btn-sm btn-download" do
=pj.document.file_name
i.fa.fa-download.ml-3 aria-hidden="true"
coffee script:
$('.btn-download').on 'click', (e) ->
id = $(this).attr('id')
$.ajax {url: Routes.document_path(id), type: 'PUT'}
routes.rb
resources :documents, only: [:show, :update]
documents_controller.rb:
def update
document = Document.find(params[:id])
authorize([:proofreaders, document])
document.update(downloaded_at: Time.current) if document.downloaded_at.nil?
head :ok
end
This seems to work very well. It updates the database and the user gets the file downloaded to their computer.