Rails 5.2 活动存储 purging/deleting 附件
Rails 5.2 Active Storage purging/deleting attachments
所以我正在使用 Active Storage 上传附加到 Collection 模型的多张图像。一切正常,除非我试图 purge/delete 来自 collection 的单个附件。
问题: 由于某种原因,每当我加载 collection 的显示页面时,我所有的图像都会立即得到 purged/deleted。当然,我只想在单击 link 时删除一个文件。有谁知道如何解决这个问题?
我的 collection 显示视图:
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove image', image.purge %>
<% end %>
</div>
我已阅读有关 http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files 的文档
(见第 4 段)
但遗憾的是,这并没有提供任何关于如何具体使用清除或 purge_later 方法的信息。
编辑
目前将我的代码更改为此(遗憾的是它仍然不起作用):
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
</div>
有了这个在我的collections_controller.rb
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to root_path
end
在我尝试删除附加图像后出现此错误:
服务器日志:
Started DELETE "/collections/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBYdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3e75276d414b4c2040e02cf0afbc083e2337faa0/delete_image_attachment" for ::1 at 2018-03-29 19:06:55 +0200
Processing by CollectionsController#delete_image_attachment as HTML
Parameters: {"authenticity_token"=>"60zIkeknxRYp/sJIWNwF+BrEftYHSCQvak34h8FkadPXgVPQSXN/sCoxI/6FU+jZbqQitES81fyqkmIx6XYp6w==", "id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBYdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3e75276d414b4c2040e02cf0afbc083e2337faa0"}
ActiveStorage::Blob Load (0.1ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = LIMIT [["id", 90], ["LIMIT", 1]]
↳ app/controllers/collections_controller.rb:69
Disk Storage (0.1ms) Deleted file from key: 8wpzqPQcWYjK2rVEejcU88FB
Disk Storage (0.0ms) Deleted files by key prefix: variants/8wpzqPQcWYjK2rVEejcU88FB/
(0.0ms) BEGIN
↳ app/controllers/collections_controller.rb:70
ActiveStorage::Blob Destroy (0.2ms) DELETE FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = [["id", 90]]
↳ app/controllers/collections_controller.rb:70
(2.0ms) COMMIT
↳ app/controllers/collections_controller.rb:70
ActiveStorage::Attachment Load (0.2ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["record_id", 90], ["record_type", "ActiveStorage::Blob"], ["name", "preview_image"], ["LIMIT", 1]]
↳ app/controllers/collections_controller.rb:70
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 2.5ms)
rake routes
的输出:
Prefix Verb URI Pattern Controller#Action
root GET / home#index
about GET /about(.:format) pages#about
contact GET /contact(.:format) pages#contact
settings GET /settings(.:format) settings#edit
new_setting GET /setting/new(.:format) settings#new
edit_setting GET /setting/edit(.:format) settings#edit
setting GET /setting(.:format) settings#show
PATCH /setting(.:format) settings#update
PUT /setting(.:format) settings#update
DELETE /setting(.:format) settings#destroy
POST /setting(.:format) settings#create
delete_image_attachment_collection DELETE /collections/:id/delete_image_attachment(.:format) collections#delete_image_attachment
collections GET /collections(.:format) collections#index
POST /collections(.:format) collections#create
new_collection GET /collections/new(.:format) collections#new
edit_collection GET /collections/:id/edit(.:format) collections#edit
collection GET /collections/:id(.:format) collections#show
PATCH /collections/:id(.:format) collections#update
PUT /collections/:id(.:format) collections#update
DELETE /collections/:id(.:format) collections#destroy
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
我的routes.rb:
Rails.application.routes.draw do
root 'home#index'
get 'about', to: 'pages#about', as: :about
get 'contact', to: 'pages#contact', as: :contact
get 'instellingen', to: 'settings#edit'
resource :setting
resources :collections do
member do
delete :delete_image_attachment
end
end
end
您正在遍历图像集合并对每个图像调用清除方法。相反,您应该 link 使用控制器上的 destroy 方法,如下所示,考虑到您的控制器操作并猜测您的路由名称。
错误是因为图像对象 returns 的完整路径和 link 认为您想要指向的内容。相反,您只需要它的 signed_id
并希望 link 调用具有您的 delete_image_attachment
路径的路由。
<%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
method: :delete,
data: { confirm: 'Are you sure?' } %>
销毁方法看起来像这样...
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to collections_url
end
路线应该是这样的...
resources :collections do
member do
delete :delete_image_attachment
end
end
查看 rails routing guide 了解更多有趣的路由信息。
好的,我有点解决了我的问题,但我真的不明白发生了什么。
每当我点击 "Remove" 按钮时,我都会收到此错误消息:
它想重定向到ID为43的collection_url(而我的collection的ID实际上是6,43可能是图片附件的ID)。
当我手动重新加载相同的 collection 页面时,图片消失了(所以它有点工作)但这当然不是理想的。
有人知道如何改进我的代码,使我的控制器中的 redirect_to 指向当前的 collection ID 而不是 Activestorage 图像附件 ID 吗?
我的文件
查看:collection/show.html.erb:
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove', delete_image_attachment_collection_url(image),
method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
</div>
控制器:collections_controller.rb
class CollectionsController < ApplicationController
before_action :set_collection, only: [:show, :edit, :update, :destroy]
before_action :set_collections
# GET /collections
# GET /collections.json
def index
end
# GET /collections/1
# GET /collections/1.json
def show
end
# GET /collections/new
def new
@collection = Collection.new
end
# GET /collections/1/edit
def edit
end
# POST /collections
# POST /collections.json
def create
@collection = Collection.new(collection_params)
respond_to do |format|
if @collection.save
format.html { redirect_to @collection, notice: 'Fotocollectie is aangemaakt.' }
format.json { render :show, status: :created, location: @collection }
else
format.html { render :new }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
# collection = Collection.create!(collection_params)
# redirect_to collection
end
# PATCH/PUT /collections/1
# PATCH/PUT /collections/1.json
def update
respond_to do |format|
if @collection.update(collection_params)
format.html { redirect_to @collection, notice: 'Fotocollectie is bijgewerkt.' }
format.json { render :show, status: :ok, location: @collection }
else
format.html { render :edit }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
end
# DELETE /collections/1
# DELETE /collections/1.json
def destroy
@collection.destroy
respond_to do |format|
format.html { redirect_to collections_url, notice: 'Fotocollectie is verwijderd.' }
format.json { head :no_content }
end
end
def delete_image_attachment
@image = ActiveStorage::Attachment.find(params[:id])
@image.purge
redirect_to @current_page
end
private
# Use callbacks to share common setup or constraints between actions.
def set_collection
@collection = Collection.find(params[:id])
end
def set_collections
@collections = Collection.all
end
# Never trust parameters from the scary internet, only allow the white list through.
def collection_params
params.require(:collection).permit(:title, :order, images: [])
end
end
型号:collection.rb
class Collection < ApplicationRecord
has_many_attached :images
end
路线:routes.rb
Rails.application.routes.draw do
root 'home#index'
get 'about', to: 'pages#about', as: :about
get 'contact', to: 'pages#contact', as: :contact
get 'settings', to: 'settings#edit'
resource :setting
resources :collections do
member do
delete :delete_image_attachment
end
end
end
感谢您更新有关 Blob 与附件的信息!清除附件后,我 redirect_back 变成我原来的形式:
def remove_attachment
attachment = ActiveStorage::Attachment.find(params[:id])
attachment.purge # or use purge_later
redirect_back(fallback_location: collections_path)
end
不是重新加载整个页面的最佳解决方案,但有效...
以下对我不起作用。
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to collections_url
end
所以我所做的就是找到附件并将其清除。你可以做purge_later,这是推荐的。
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.attachments.first.purge
redirect_to collections_url
end
这删除了附件和 blob 记录。
如果您来到这里是想通过 rails 控制台删除附件。
单个附件
user.image.purge
对于多个附件:
user.images.purge
来源:https://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files
所以我正在使用 Active Storage 上传附加到 Collection 模型的多张图像。一切正常,除非我试图 purge/delete 来自 collection 的单个附件。
问题: 由于某种原因,每当我加载 collection 的显示页面时,我所有的图像都会立即得到 purged/deleted。当然,我只想在单击 link 时删除一个文件。有谁知道如何解决这个问题?
我的 collection 显示视图:
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove image', image.purge %>
<% end %>
</div>
我已阅读有关 http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files 的文档 (见第 4 段)
但遗憾的是,这并没有提供任何关于如何具体使用清除或 purge_later 方法的信息。
编辑 目前将我的代码更改为此(遗憾的是它仍然不起作用):
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
</div>
有了这个在我的collections_controller.rb
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to root_path
end
在我尝试删除附加图像后出现此错误:
服务器日志:
Started DELETE "/collections/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBYdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3e75276d414b4c2040e02cf0afbc083e2337faa0/delete_image_attachment" for ::1 at 2018-03-29 19:06:55 +0200
Processing by CollectionsController#delete_image_attachment as HTML
Parameters: {"authenticity_token"=>"60zIkeknxRYp/sJIWNwF+BrEftYHSCQvak34h8FkadPXgVPQSXN/sCoxI/6FU+jZbqQitES81fyqkmIx6XYp6w==", "id"=>"eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBYdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3e75276d414b4c2040e02cf0afbc083e2337faa0"}
ActiveStorage::Blob Load (0.1ms) SELECT "active_storage_blobs".* FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = LIMIT [["id", 90], ["LIMIT", 1]]
↳ app/controllers/collections_controller.rb:69
Disk Storage (0.1ms) Deleted file from key: 8wpzqPQcWYjK2rVEejcU88FB
Disk Storage (0.0ms) Deleted files by key prefix: variants/8wpzqPQcWYjK2rVEejcU88FB/
(0.0ms) BEGIN
↳ app/controllers/collections_controller.rb:70
ActiveStorage::Blob Destroy (0.2ms) DELETE FROM "active_storage_blobs" WHERE "active_storage_blobs"."id" = [["id", 90]]
↳ app/controllers/collections_controller.rb:70
(2.0ms) COMMIT
↳ app/controllers/collections_controller.rb:70
ActiveStorage::Attachment Load (0.2ms) SELECT "active_storage_attachments".* FROM "active_storage_attachments" WHERE "active_storage_attachments"."record_id" = AND "active_storage_attachments"."record_type" = AND "active_storage_attachments"."name" = LIMIT [["record_id", 90], ["record_type", "ActiveStorage::Blob"], ["name", "preview_image"], ["LIMIT", 1]]
↳ app/controllers/collections_controller.rb:70
Redirected to http://localhost:3000/
Completed 302 Found in 5ms (ActiveRecord: 2.5ms)
rake routes
的输出:
Prefix Verb URI Pattern Controller#Action
root GET / home#index
about GET /about(.:format) pages#about
contact GET /contact(.:format) pages#contact
settings GET /settings(.:format) settings#edit
new_setting GET /setting/new(.:format) settings#new
edit_setting GET /setting/edit(.:format) settings#edit
setting GET /setting(.:format) settings#show
PATCH /setting(.:format) settings#update
PUT /setting(.:format) settings#update
DELETE /setting(.:format) settings#destroy
POST /setting(.:format) settings#create
delete_image_attachment_collection DELETE /collections/:id/delete_image_attachment(.:format) collections#delete_image_attachment
collections GET /collections(.:format) collections#index
POST /collections(.:format) collections#create
new_collection GET /collections/new(.:format) collections#new
edit_collection GET /collections/:id/edit(.:format) collections#edit
collection GET /collections/:id(.:format) collections#show
PATCH /collections/:id(.:format) collections#update
PUT /collections/:id(.:format) collections#update
DELETE /collections/:id(.:format) collections#destroy
rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
我的routes.rb:
Rails.application.routes.draw do
root 'home#index'
get 'about', to: 'pages#about', as: :about
get 'contact', to: 'pages#contact', as: :contact
get 'instellingen', to: 'settings#edit'
resource :setting
resources :collections do
member do
delete :delete_image_attachment
end
end
end
您正在遍历图像集合并对每个图像调用清除方法。相反,您应该 link 使用控制器上的 destroy 方法,如下所示,考虑到您的控制器操作并猜测您的路由名称。
错误是因为图像对象 returns 的完整路径和 link 认为您想要指向的内容。相反,您只需要它的 signed_id
并希望 link 调用具有您的 delete_image_attachment
路径的路由。
<%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id),
method: :delete,
data: { confirm: 'Are you sure?' } %>
销毁方法看起来像这样...
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to collections_url
end
路线应该是这样的...
resources :collections do
member do
delete :delete_image_attachment
end
end
查看 rails routing guide 了解更多有趣的路由信息。
好的,我有点解决了我的问题,但我真的不明白发生了什么。
每当我点击 "Remove" 按钮时,我都会收到此错误消息:
它想重定向到ID为43的collection_url(而我的collection的ID实际上是6,43可能是图片附件的ID)。
当我手动重新加载相同的 collection 页面时,图片消失了(所以它有点工作)但这当然不是理想的。
有人知道如何改进我的代码,使我的控制器中的 redirect_to 指向当前的 collection ID 而不是 Activestorage 图像附件 ID 吗?
我的文件
查看:collection/show.html.erb:
<div id="gallery">
<% @collection.images.each do |image| %>
<%= image_tag(image) %>
<%= link_to 'Remove', delete_image_attachment_collection_url(image),
method: :delete,
data: { confirm: 'Are you sure?' } %>
<% end %>
</div>
控制器:collections_controller.rb
class CollectionsController < ApplicationController
before_action :set_collection, only: [:show, :edit, :update, :destroy]
before_action :set_collections
# GET /collections
# GET /collections.json
def index
end
# GET /collections/1
# GET /collections/1.json
def show
end
# GET /collections/new
def new
@collection = Collection.new
end
# GET /collections/1/edit
def edit
end
# POST /collections
# POST /collections.json
def create
@collection = Collection.new(collection_params)
respond_to do |format|
if @collection.save
format.html { redirect_to @collection, notice: 'Fotocollectie is aangemaakt.' }
format.json { render :show, status: :created, location: @collection }
else
format.html { render :new }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
# collection = Collection.create!(collection_params)
# redirect_to collection
end
# PATCH/PUT /collections/1
# PATCH/PUT /collections/1.json
def update
respond_to do |format|
if @collection.update(collection_params)
format.html { redirect_to @collection, notice: 'Fotocollectie is bijgewerkt.' }
format.json { render :show, status: :ok, location: @collection }
else
format.html { render :edit }
format.json { render json: @collection.errors, status: :unprocessable_entity }
end
end
end
# DELETE /collections/1
# DELETE /collections/1.json
def destroy
@collection.destroy
respond_to do |format|
format.html { redirect_to collections_url, notice: 'Fotocollectie is verwijderd.' }
format.json { head :no_content }
end
end
def delete_image_attachment
@image = ActiveStorage::Attachment.find(params[:id])
@image.purge
redirect_to @current_page
end
private
# Use callbacks to share common setup or constraints between actions.
def set_collection
@collection = Collection.find(params[:id])
end
def set_collections
@collections = Collection.all
end
# Never trust parameters from the scary internet, only allow the white list through.
def collection_params
params.require(:collection).permit(:title, :order, images: [])
end
end
型号:collection.rb
class Collection < ApplicationRecord
has_many_attached :images
end
路线:routes.rb
Rails.application.routes.draw do
root 'home#index'
get 'about', to: 'pages#about', as: :about
get 'contact', to: 'pages#contact', as: :contact
get 'settings', to: 'settings#edit'
resource :setting
resources :collections do
member do
delete :delete_image_attachment
end
end
end
感谢您更新有关 Blob 与附件的信息!清除附件后,我 redirect_back 变成我原来的形式:
def remove_attachment
attachment = ActiveStorage::Attachment.find(params[:id])
attachment.purge # or use purge_later
redirect_back(fallback_location: collections_path)
end
不是重新加载整个页面的最佳解决方案,但有效...
以下对我不起作用。
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.purge
redirect_to collections_url
end
所以我所做的就是找到附件并将其清除。你可以做purge_later,这是推荐的。
def delete_image_attachment
@image = ActiveStorage::Blob.find_signed(params[:id])
@image.attachments.first.purge
redirect_to collections_url
end
这删除了附件和 blob 记录。
如果您来到这里是想通过 rails 控制台删除附件。
单个附件
user.image.purge
对于多个附件:
user.images.purge
来源:https://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files