Rails 5.2 Active Storage purging/deleting attachments

后端 未结 4 2086
醉话见心
醉话见心 2020-12-06 05:19

So I\'m using Active Storage to upload multiple images attached to a Collection model. Everything works well except whenever I\'m trying to purge/delete a single attachment

相关标签:
4条回答
  • 2020-12-06 05:49

    You are looping through the collection of images and calling the purge method on each one. Instead you should be linking to a destroy method on your controller, something like the below taking into account your controller actions and guessing at your route names.

    The error is because image object returns its full path and the link thinks that what you want to point to. Instead you just want its signed_id and want the link to call the route that has your delete_image_attachment path.

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

    The destroy method would look something like this...

    def delete_image_attachment
      @image = ActiveStorage::Blob.find_signed(params[:id])
      @image.purge
      redirect_to collections_url
    end
    

    The route should be something like so...

    resources :collections do
      member do
        delete :delete_image_attachment
      end
    end
    

    Check out the rails routing guide for more fun routing facts.

    0 讨论(0)
  • 2020-12-06 05:49

    Okay I sort of solved my problem but I don't really understand what's happening.

    Whenever I click on the "Remove" button I get this error:

    It wants to redirect to the collection_url with ID 43 (while the ID of my collection is actually 6, 43 is probably the ID of the image attachment).

    When I reload the same collection page manually, the picture is gone (so it sort of works) but nothing of this is ofcourse ideal.

    Does someone know how I can improve my code so that the redirect_to in my controller points to the current collection ID instead of the Activestorage image attachment ID?

    My files

    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
    
    0 讨论(0)
  • 2020-12-06 06:00

    The following didn't work for me.

    def delete_image_attachment
      @image = ActiveStorage::Blob.find_signed(params[:id])
      @image.purge
      redirect_to collections_url
    end
    

    So what i did is found the attachment and purged it. You can do purge_later which is recommended.

    def delete_image_attachment
      @image = ActiveStorage::Blob.find_signed(params[:id])
      @image.attachments.first.purge
      redirect_to collections_url
    end
    

    This removed both attachment and blob record.

    0 讨论(0)
  • 2020-12-06 06:05

    Thanks for your update regarding Blob vs Attachment! After purging the attachment I redirect_back to the form I came from like this:

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

    Not the best solution to reload the entire page but works ...

    0 讨论(0)
提交回复
热议问题