You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Controller路由更新active字段为false的实现问题

Hey there! Let's break down how to get this soft-delete (and admin hard-delete) workflow working smoothly for your Document model—this audit-friendly setup makes total sense, so let's fix that routing/action issue you're hitting.

Step 1: Define Custom Routes

First, we need to add routes for your non-standard delete actions, since the default destroy action is meant for permanent deletion. Open your config/routes.rb and update your documents resources:

resources :documents do
  member do
    patch 'soft_delete'  # Use PATCH for updating the document's active status
    delete 'hard_delete' # Use DELETE for permanent removal (admin-only)
  end
end

You can verify these routes exist by running rails routes in your terminal—look for paths like /documents/:id/soft_delete and /documents/:id/hard_delete.

Step 2: Add Controller Actions

Next, head to your DocumentsController and add the two new actions, along with permission checks to keep things secure.

Soft Delete Action (For Regular Users)

This action will set the active column to false instead of deleting the record:

def soft_delete
  @document = Document.find(params[:id])
  
  # Optional: Add logic to verify the current user owns this document
  # unless @document.user == current_user
  #   redirect_to documents_path, alert: "You can't modify this document."
  #   return
  # end

  if @document.update(active: false)
    redirect_to documents_path, notice: 'Document was successfully marked as inactive.'
  else
    redirect_to documents_path, alert: 'Failed to mark document as inactive.'
  end
end

Hard Delete Action (Admin-Only)

This action will permanently delete the record, but only for authorized admins:

def hard_delete
  # First, block non-admin users
  unless current_user&.admin?
    redirect_to documents_path, alert: 'You are not authorized to permanently delete documents.'
    return
  end

  @document = Document.find(params[:id])
  
  # Optional: If you're using Active Storage/CarrierWave, purge the attached file first
  # @document.uploaded_file.purge # Adjust based on your attachment column name

  if @document.destroy
    redirect_to documents_path, notice: 'Document was permanently deleted.'
  else
    redirect_to documents_path, alert: 'Failed to permanently delete the document.'
  end
end

To keep permission logic clean, you can also extract the admin check into a private method and use a before_action:

before_action :authorize_admin!, only: [:hard_delete]

private

def authorize_admin!
  unless current_user&.admin?
    redirect_to root_path, alert: 'Access denied.'
  end
end
Step 3: Update Your Views

Now, add the appropriate buttons to your views so users can trigger these actions.

Regular User View (Soft Delete Button)

Show this button only for active documents:

<% if @document.active %>
  <%= button_to 'Mark as Inactive', soft_delete_document_path(@document), method: :patch, class: 'btn btn-warning' %>
<% else %>
  <span class="text-muted">Document is inactive</span>
<% end %>

Admin View (Hard Delete Button)

Add this button only for admins (you might want to show it only for inactive documents too, depending on your workflow):

<% if current_user.admin? %>
  <%= button_to 'Permanently Delete', hard_delete_document_path(@document), method: :delete, class: 'btn btn-danger', data: { confirm: 'Are you sure? This action cannot be undone!' } %>
<% end %>
Step 4: Optional - Scope Queries for Active Documents

To make sure regular users only see active documents by default, add a scope to your Document model:

class Document < ApplicationRecord
  scope :active, -> { where(active: true) }
end

Then update your index action in the controller:

def index
  @documents = current_user.admin? ? Document.all : Document.active.all
end
Troubleshooting Quick Checks
  • Missing active column? Run a migration to add it:
    rails generate migration AddActiveToDocuments active:boolean
    
    Then open the migration file and set a default value:
    def change
      add_column :documents, :active, :boolean, default: true
    end
    
    Run rails db:migrate to apply it.
  • Routing errors? Double-check that you're using the correct path helper (e.g., soft_delete_document_path(@document) instead of document_soft_delete_path). Run rails routes to confirm.
  • Permission issues? Test with both regular and admin users to ensure actions are restricted correctly.

内容的提问来源于stack exchange,提问作者Ben Pohl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:08:17