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

Active Storage图片上传后无法显示:404 NotFound错误求助

问题

使用Active Storage上传图片后无法正常显示,已确认image_blob已创建且图片数据已附加到实例,但图片仍无法渲染。


相关代码

Model(work.rb)

has_one_attached :work_image
has_one_attached :proposal_image
has_one_attached :development_image
has_one_attached :design_image
has_one_attached :result_image
has_one_attached :client_voice_image
has_one_attached :additional_section_image
has_one_attached :additional_section2_image

注:设置多个has_one_attached是因为每张图片需要在特定位置展示。

Controller(admin/works_controller.rb)

def new
  @work = Work.new
end

def submit
  @work = Work.new(work_params) # 创建新的Work实例
  if @work.save # 保存Work
    process_tags
    redirect_to preview_admin_work_path(@work)
  else
    render :new
  end
end

def preview
  @work = Work.find_by(id: params[:id])
end
...
private

def work_params
    params.require(:work).permit(
      :work_image,
      :work_title,
      :release_date,
      :client_name,
      :service_name,
      :service_url,
         ......
      :development_image,
      :proposal_image,
      :design_image,
      :result_image,
      :client_voice_image,
      :additional_section_image,
      :additional_section2_image,
      tag_ids: []
    )
end
def process_tags
  if params[:work][:tag_ids].present?
    tag_ids = if params[:work][:tag_ids].is_a?(Array)
                params[:work][:tag_ids].map(&:to_i)
              else
                params[:work][:tag_ids].split(',').map(&:to_i)
              end
    @work.tags = Tag.where(id: tag_ids)
  end
end

View(new.html.erb)

<%= form_for @work, url: submit_admin_works_path, local: true, multipart: true do |f| %>
....
    <div class="mt-3">
      <%= f.label :work_image, "サムネイル画像を登録<span class='required'>   ※必須</span>".html_safe, class: "form-label" %>
      <%= f.file_field :work_image, class: 'form-control' %>
    </div>
....
<% end %>

注:show/edit页面表单逻辑与上述一致,仅提交URL不同。

View(preview.html.erb)

...
<%= image_tag @work.work_image, alt: 'Work Image' %>  
...

排查与解决方法

1. 修复预览页面的实例查询逻辑

preview动作中使用find_by会在ID无效时返回nil,导致后续调用图片方法无反应。改成find强制抛出异常,方便快速定位问题:

def preview
  @work = Work.find(params[:id]) # 替换find_by为find
end

2. 确认图片是否真的附加成功

在预览页面或控制台打印@work.work_image.attached?,返回true才说明图片已正确附加。如果返回false,检查:

  • 表单multipart: true是否配置(你的代码已正确设置)
  • work_params中图片字段是否拼写正确(确认无漏写或错写)
  • 保存时是否有错误,可在submit动作中添加puts @work.errors.full_messages输出错误信息

3. 检查Active Storage服务配置

打开config/storage.yml,确认存储服务配置:

  • 本地存储需确保public: true,否则图片路径为签名URL,可能因权限无法访问:
local:
  service: Disk
  root: <%= Rails.root.join("storage") %>
  public: true
  • 云存储(如S3)需确认Bucket权限、Access Key等配置正确

4. 验证图片URL的可访问性

在浏览器中查看图片的src属性,复制URL直接访问:

  • 本地存储URL类似/rails/active_storage/blobs/xxxx/xxx.jpg,若404则检查storage目录是否存在对应文件,以及config/routes.rb是否加载了Active Storage路由(需包含rails_active_storage.routes.draw)
  • 签名URL需检查是否过期或配置错误

5. 优化图片渲染的容错逻辑

在视图中增加图片附加判断,避免空实例报错:

<% if @work.work_image.attached? %>
  <%= image_tag @work.work_image, alt: 'Work Image' %>
<% else %>
  <p>未上传图片</p>
<% end %>

6. 检查Rails版本兼容性

部分旧版本Rails的Active Storage存在已知问题,建议升级到当前大版本的最新稳定版。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:09:52