I am trying to make a general files uploader for all the files and images for my Rails app. The uploader function is the same like the popular JS uploaders such as Filestack or Uppy Uploader, where the users just select any file on their browser, then the app will process the file and return back the file's URL after it has been uploaded. Now, with this URL, we can then attach it to any form/WYSIWYG editor/wherever we like such as in Chat message etc.
For this purpose, my approach is to do a manual upload using Rails Active Storage.
So firstly, I make a Class called Uploader which is linked to Rails Active Storage:
app/models/uploader.rb
class Uploader < ApplicationRecord
has_one_attached :file
end
Then, I created a Controller for this Uploader with an action called "file", where all the files will be processed:
config/routes.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
Finally, this is the view of this Uploader:
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 %>
QUESTION
So, my question is how do I use JSON in the above codes so that I could fetch the uploaded file URL?
To start with, I have changed the above codes, to these:
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>
Now, I am using javascript to submit the active storage form through JSON. But clearly something is missing as the script does not handle any active storage at the moment. So, how do i solve this?
Thanks!
JSON.stringify({ file: $("#uploader_file"), _method: 'post' })
– Зелёный