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

Rails基于Devise认证的相册多图上传场景下单张图片删除实现

单张图片删除功能实现全流程

一、现有代码的核心问题

  • 语法层面错误:current_user.albums.ActiveStorage::Blob.find(params[:id]) 不符合Ruby/Rails的调用规范,根本无法正常执行,访问该方法时会直接抛出语法类报错。
  • 安全层面风险:如果绕过语法问题直接全局查询ActiveStorage::Blob,全程没有校验图片和当前登录用户的归属关系,攻击者可以篡改请求参数删除任意用户的图片,存在越权操作的重大隐患。
  • 体验层面缺陷:删除完成后固定重定向到albums_path列表页,会强制打断用户在相册详情页的操作流,不符合常规交互逻辑。

二、修正后的控制器实现

调整delete_image_attachment方法的逻辑,补全权限校验、修正查询逻辑、优化跳转行为:

def delete_image_attachment
  # 仅查找当前登录用户名下的相册,完成第一层权限校验
  @album = current_user.albums.find(params[:id])
  # 仅在当前相册的图片集合内查找待删除的附件,完成第二层权限校验
  @image = @album.images.find(params[:image_id])
  # 同步删除图片的存储文件和数据库关联记录
  @image.purge
  # 跳转回当前相册详情页,保留用户操作上下文
  redirect_to @album, notice: "图片删除成功"
end

三、路由正确配置方式

在现有resources :albums的嵌套路由块内新增图片删除的路由规则,不需要新增独立的控制器:

Rails.application.routes.draw do
  devise_for :users 
  root to: "albums#index"
  resources :albums do 
    resources :comments
    # 新增DELETE类型路由,绑定到Albums控制器的图片删除方法
    delete "images/:image_id", to: "albums#delete_image_attachment", on: :member, as: :delete_image
  end
end

配置完成后,Rails会自动生成名为delete_image_album的路径辅助方法,对应请求路径为/albums/:id/images/:image_id,请求方法为DELETE,和控制器的参数逻辑完全匹配。

四、Show页面删除链接编写

在相册详情页循环渲染单张图片时,直接调用生成的路由辅助方法拼接链接即可:

<% @album.images.each do |image| %>
  <div class="p-2">
    <%= image_tag image, class: "w-full" %>
    <%# 补全链接的路径参数,保留原有的删除请求方法和二次确认逻辑 %>
    <%= link_to 'Remove', delete_image_album_path(@album, image), method: :delete, data: {confirm: "Are You Sure ?"} %>
  </div>
<% end %>

链接参数说明

  • delete_image_album_path 接收两个入参:第一个传入当前的@album对象,Rails会自动提取其id作为路由中:id参数的值;第二个传入循环到的单个图片附件对象,Rails会自动提取其id作为路由中:image_id参数的值。
  • 保留原有method: :delete配置,和路由定义的请求类型保持一致;data-confirm配置的二次确认弹窗逻辑不需要额外修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.25 00:36:05