首页 文章

Rails 5.2 Active Storage清除/删除附件

提问于
浏览
6

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

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

我的收藏展示视图:

<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或purge_later方法的任何信息 .

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

<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

在我尝试删除附加图像后,这给了我这个错误:

Error I get when returning to the collection show after (trying to) delete an image.

服务器日志:

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

3 回答

  • 8

    您循环遍历图像集合并在每个图像上调用清除方法 . 相反,您应该链接到控制器上的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 routing guide以获取更多有趣的路由事实 .

  • 3

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

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

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

  • 1

    好吧,我有点解决了我的问题,但我没有发生 .

    每当我点击"Remove"按钮时,我都会收到此错误:

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

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

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

    我的档案

    View: 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>
    

    Controller: 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
    

    Model: collection.rb

    class Collection < ApplicationRecord
      has_many_attached :images
    end
    

    Routes: 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
    

相关问题