Загрузка вручную с использованием Active Storage с JSON - PullRequest
0 голосов
/ 27 сентября 2018

Я пытаюсь сделать общий загрузчик файлов для всех файлов и изображений для моего приложения Rails.Функция загрузки аналогична популярным загрузчикам JS, таким как Filestack или Uppy Uploader , где пользователи просто выбирают любой файл в своем браузере, затем приложение обрабатывает файл и возвращаетвернуться к URL-адресу файла после его загрузки.Теперь с помощью этого URL мы можем присоединить его к любому редактору форм / WYSIWYG / где угодно, например, в сообщениях чата и т. Д.

Для этой цели мой подход заключается в том, чтобы выполнить загрузку вручную с помощью Rails Active Storage.,

Итак, во-первых, я создаю класс с именем Uploader, который связан с Rails Active Storage:

app / models / uploader.rb

class Uploader < ApplicationRecord
  has_one_attached :file
end

Затем я создал контроллер для этого загрузчика с действием «file», в котором будут обрабатываться все файлы:

config / rout.rb

post 'uploaders/file' => 'uploaders#file'

app / controllers / uploaders_controller.rb

  def file
    blob = ActiveStorage::Blob.create_after_upload!(
      io: params[:uploader][:file],
      filename: params[:uploader][:file].original_filename,
      content_type: params[:uploader][:file].content_type
    )

    @filelink = url_for(blob)

    respond_to do |format|
      format.html { redirect_back(fallback_location: root_path) }
      format.js
    end
  end

Наконец, это представление этого загрузчика:

app / views / new.html.erb

<h3>Select Files To Upload</h3>

<%= form_for @uploader, url: uploaders_file_path(@uploader), remote: true do |f| %>
  <%= f.file_field :file, direct_upload: true,  class: "form-control" %>

  <%= f.button type: "submit", id: "submit-uploader", class: "btn btn-primary btn-md", data: {disable_with: "Uploading..."} do %>
    Save
  <% end %>
<% end %>

ВОПРОС

Итак, мой вопрос, как мне использовать JSON в приведенных выше кодах, чтобы я мог получитьURL загруженного файла?

Для начала я изменил приведенные выше коды на следующие:

app / controllers / uploaders_controller.rb

  def file
    blob = ActiveStorage::Blob.create_after_upload!(
      io: params[:uploader][:file],
      filename: params[:uploader][:file].original_filename,
      content_type: params[:uploader][:file].content_type
    )

    render json: { filelink: url_for(blob) }
  end

app / views / new.html.erb

<%= form_for @uploader, url: uploaders_file_path(@uploader), remote: true, :html => {:'data-type' => 'json', :multipart => true} do |f| %>
  <%= f.file_field :file, direct_upload: true,  class: "form-control" %>

  <%= f.button type: "submit", id: "submit-uploader", class: "btn btn-primary btn-md", data: {disable_with: "Uploading..."} do %>
    Save
  <% end %>
<% end %>

<script type="text/javascript">
  $("#submit-uploader").click(function(e){
    e.preventDefault();

    $.ajax({
      type: "POST",
      dataType: "script",
      url: $(this).parents("form").attr("action"),
      contentType: 'application/json',
      data: JSON.stringify({ file: $("#uploader_file"), _method: 'post' })
    }).done(function( data ){
      console.log(data);
    });
  });
</script>

Теперь я использую javascript для отправки активной формы хранения через JSON.Но, очевидно, чего-то не хватает, так как скрипт не обрабатывает ни одного активного хранилища в данный момент.Итак, как мне решить эту проблему?

Спасибо!

1 Ответ

0 голосов
/ 27 сентября 2018

Вы можете отправить файл с помощью ajax, вот пример :

<%= form_tag uploaders_file_path(@uploader), :html => {:multipart => true} do |f| %>
  <%= f.file_field :file, direct_upload: true,  class: "form-control" %>

  <%= f.button type: "submit", id: "submit-uploader", class: "btn btn-primary btn-md", data: {disable_with: "Uploading..."} do %>
    Save
  <% end %>
<% end %>

<script type="text/javascript">
  // trigger the form submit 
  $("form").submit(function(evt){   
    evt.preventDefault();
    // get the input with file
    var formData = new FormData($(this)[0]);

    $.ajax({
       url: "<%= uploaders_file_path(@uploader) %>",
       type: 'POST',
       data: formData,
       async: false,
       cache: false,
       contentType: false,
       enctype: 'multipart/form-data',
       processData: false,
       success: function (response) {
         alert(response);
       }
   });
   return false;
  })
</script>
...