Как обновить базу данных, когда пользователи загружают вложение блоба ActiveStorage? - PullRequest
5 голосов
/ 06 июля 2019

В настоящее время пользователи могут загрузить BLOB-объект ActiveStorage в моем приложении, используя следующую ссылку:

link_to 'download', rails_blob_path(pj.document.file, disposition: 'attachment')

Однако я хотел бы обновить атрибут в базе данных для связанной модели, чтобы он регистрировался при первой загрузке файла. Это поле называется полем download_at.

Я предпринял следующую попытку:

  1. Изменено link_to> button_to при обновлении модели.
  2. Добавлен соответствующий маршрут
  3. Добавлен следующий код в базу данных:

    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
    

Однако, это не делает ничего, кроме перенаправления на страницу @proofreading_job, что мне не нужно.

Кто-нибудь делал это раньше, и если да, как я могу выполнить эту задачу.

Ответы [ 2 ]

0 голосов
/ 16 июля 2019

В конце концов, я просто использовал некоторый JavaScript, чтобы зафиксировать нажатие кнопки следующим образом:

    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"

сценарий кофе:

  $('.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

Кажется, это работает очень хорошо. Он обновляет базу данных, и пользователь получает файл, загруженный на его компьютер.

0 голосов
/ 15 июля 2019

Я думаю, вы также можете попробовать использовать свой контроллер действий в качестве прокси, концепция такова:

  1. скачайте файл в вашем действии
  2. проверить, успешно ли он загружен, и другие проверки
  3. выполнить операции очистки (в вашем случае добавленный код в # 3)
  4. отправить файл обратно пользователю, используя send_data / send_file метод рендеринга

например. в вашем контроллере:

def download
  file = open(params[:uri])
  validate!
  cleanup!
  send_file file.path
end

Тогда по вашему мнению:

link_to 'download', your_controller_path

Выше - просто концепция, и я прошу прощения за предоставление только псевдокода заранее.

...