Skip to main content

Struggling with Active Storage delete/purge on uploads

Rails • Asked by spacerobotTR

Fallback

I have a projects model. A project could have many uploads that could be anything (pdf, word, cad, image etc.) I have the uploading working and I am displaying links to the files on the projects/show page. I want to have a delete button next to the file links to be able to purge them when the link is clicked. I am getting all sorts of routing errors though.

When I click the Remove link_to I am getting the error: No route matches [GET] "/projects/1/delete_upload/2"

Any help or suggestions would be appreciated!

Here is what I have:

Projects Controller:

class ProjectsController < ApplicationController
  before_action :set_project, only: [:show, :edit, :update, :destroy]

  # GET /projects
  # GET /projects.json
  def index
    @projects = Project.joins(:proj_status).order("created_at DESC")
    @title = 'Projects - Summary'
  end

  # GET /projects/1
  # GET /projects/1.json
  def show
    @projects = Project.joins(:proj_status).order("created_at DESC")

  end

  def delete_upload
    @attachment = ActiveStorage::Attachment.find(params[:upload_id])
    @attachment.purge # or use purge_later
    redirect_back(fallback_location: projects_path)
  end

  # GET /projects/new
  def new
    @project = Project.new
  end

  # GET /projects/1/edit
  def edit
  end

  # POST /projects
  # POST /projects.json
  def create
    @project = current_user.projects.build(project_params)
    respond_to do |format|
      if @project.save

        format.html { redirect_to @project, notice: 'Project was successfully created.' }
        format.json { render :show, status: :created, location: @project }
      else
        format.html { render :new }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /projects/1
  # PATCH/PUT /projects/1.json
  def update
    respond_to do |format|
      if @project.update(project_params)
        format.html { redirect_to @project, notice: 'Project was successfully updated.' }
        format.json { render :show, status: :ok, location: @project }
      else
        format.html { render :edit }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /projects/1
  # DELETE /projects/1.json
  def destroy
    @project.destroy
    respond_to do |format|
      format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_project
      @project = Project.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def project_params
        params.require(:project).permit(:projname, :startdate, :enddate,
          :installer, :createdby, :cpdcprojnum, :projmanager, :customername, :customerphone,
          :customeremail, :projtype, :building, :rooms, :description, :status_id, uploads: [])
    end
end

Projects Show page:

<% @project.uploads.each do |upload| %>
              <li class="list-group-item">
                <div class="media align-items-center">
                  <div class="media-body px-2">
                    <%= link_to upload.filename, rails_blob_path(upload, disposition: :attachment) %> - &nbsp;&nbsp;
                    <%= link_to 'Remove', url_for(controller: :projects, action: :delete_upload, id: @project.id, upload_id: upload.id), data: { confirm: 'Are you sure?' } %>
                  </div>
                  <a href="javascript:void(0)" class="d-block text-light text-large font-weight-light">&times;</a>
                </div>
              </li>
              <% end %>

Routes:

  resources :projects do
  member do
    delete "delete_upload/:upload_id", action: :delete_upload
  end
end

Fallback

No route matches [GET] "/projects/1/delete_upload/2"

You made a GET request to the url, but your routes define a DELETE route.

You must add method: :delete to your link.


Fallback

So changing the link to this:

url_for(controller: :projects, action: :delete_upload, id: @project.id, upload_id: upload.id), method: :delete, data: { confirm: 'Are you sure?' }

Adding the method: delete produces this error:

No route matches [GET] "/projects/1/delete_upload/2"


Fallback

Still made a GET request, so you know that your Rails UJS Javascript is broken if it's not making a DELETE request.


Fallback

Ahhh gotcha. I'll have to chase that down then. Thanks for the help.


Fallback

I figured it out. Somehow must have removed the reference to include the application.js file in my application.html.erb. Adding that back in has resolved the issue!


Fallback

Great! Glad you got it working. 🙌


Login or create an account to join the conversation.