Rails 5.2 Active Storage清除/删除附件

所以我使用Active Storage上传附加到Collection模型的多个图像。 除非我试图从集合中清除/删除单个附件,否则一切都很顺利。

问题:出于某种原因,每当我加载集合的显示页面时,我的所有图像都会立即被清除/删除。 当然,我只想在点击链接时删除文件。 有谁知道如何解决这个问题?

我的collections展示视图:

 

我已经阅读了http://edgeguides.rubyonrails.org/active_storage_overview.html#removing-files上的文档(参见第4段)

但遗憾的是,这并未提供有关如何专门使用purge或purge_later方法的任何信息。

编辑目前将我的代码更改为此(仍然遗憾地无效):

  

在我的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" = $1 LIMIT $2 [["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" = $1 [["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" = $1 AND "active_storage_attachments"."record_type" = $2 AND "active_storage_attachments"."name" = $3 LIMIT $4 [["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 

您循环遍历图像集合并在每个图像上调用清除方法。 相反,您应该链接到控制器上的destroy方法,如下所示,考虑到您的控制器操作并猜测您的路由名称。

错误是因为图像对象返回其完整路径,并且链接认为您想要指向的内容。 相反,你只需要它的signed_id并希望链接调用具有delete_image_attachment路径的路由。

  <%= link_to 'Remove', delete_image_attachment_collections_url(image.signed_id), method: :delete, data: { confirm: 'Are you sure?' } %> 

destroy方法看起来像这样……

 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路由指南 ,了解更多有趣的路由事实。

感谢您关于Blob vs Attachment的更新! 清除附件后,我将redirect_back改为我来自的forms,如下所示:

 def remove_attachment attachment = ActiveStorage::Attachment.find(params[:id]) attachment.purge # or use purge_later redirect_back(fallback_location: collections_path) end 

不是重新加载整个页面的最佳解决方案,但有效…

好吧,我有点解决了我的问题,但我真的不明白发生了什么。

每当我点击“删除”按钮时,我都会收到此错误:

它想要重定向到ID为43的collection_url(而我的集合的ID实际上是6,43可能是图像附件的ID)。

当我手动重新加载相同的收集页面时,图片消失了(所以它有点工作),但这不是理想的。

有人知道我如何改进我的代码,以便我的控制器中的redirect_to指向当前的集合ID而不是Activestorage图像附件ID?

我的文件

查看:collection / show.html.erb:

  

控制器: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