Skip to main content

Struggling with Active Storage delete/purge on uploads

Rails • Asked by spacerobotTR
2fa78348f5d312a02e2311802b201c97

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

Ce795239ba5dd2384fc2f88ffaff5451

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.


2fa78348f5d312a02e2311802b201c97

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"


Ce795239ba5dd2384fc2f88ffaff5451

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


2fa78348f5d312a02e2311802b201c97

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


2fa78348f5d312a02e2311802b201c97

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!


Ce795239ba5dd2384fc2f88ffaff5451

Great! Glad you got it working. 🙌


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 18,000+ developers who get early access to new screencasts, articles, guides, updates, and more.

By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

More of a social being? We're also on Twitter and YouTube.