使用 JSON 的 Active Storage 手动上传
Manual uploads using Active Storage with JSON
我正在尝试为我的 Rails 应用程序的所有文件和图像制作一个通用文件上传器。上传器功能与流行的 JS 上传器相同,例如 Filestack or Uppy Uploader,用户只需 select 浏览器上的任何文件,然后应用程序将处理该文件并 return 返回文件的URL 上传后。现在,有了这个 URL,我们就可以将它附加到我们喜欢的任何 form/WYSIWYG editor/wherever,例如聊天消息等
为此,我的方法是使用 Rails Active Storage 进行手动上传。
所以首先,我创建了一个名为 Uploader 的 Class,它链接到 Rails Active Storage:
app/models/uploader.rb
class Uploader < ApplicationRecord
has_one_attached :file
end
然后,我为此上传器创建了一个控制器,其中包含一个名为 "file" 的操作,其中将处理所有文件:
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
最后,这是这个上传者的观点:
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提交活动存储表。但显然缺少一些东西,因为脚本目前不处理任何活动存储。那么,我该如何解决这个问题?
谢谢!
您可以使用 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>
我正在尝试为我的 Rails 应用程序的所有文件和图像制作一个通用文件上传器。上传器功能与流行的 JS 上传器相同,例如 Filestack or Uppy Uploader,用户只需 select 浏览器上的任何文件,然后应用程序将处理该文件并 return 返回文件的URL 上传后。现在,有了这个 URL,我们就可以将它附加到我们喜欢的任何 form/WYSIWYG editor/wherever,例如聊天消息等
为此,我的方法是使用 Rails Active Storage 进行手动上传。
所以首先,我创建了一个名为 Uploader 的 Class,它链接到 Rails Active Storage:
app/models/uploader.rb
class Uploader < ApplicationRecord
has_one_attached :file
end
然后,我为此上传器创建了一个控制器,其中包含一个名为 "file" 的操作,其中将处理所有文件:
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
最后,这是这个上传者的观点:
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提交活动存储表。但显然缺少一些东西,因为脚本目前不处理任何活动存储。那么,我该如何解决这个问题?
谢谢!
您可以使用 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>