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

Rails 7.1.3中如何用Ransack搜索ActiveStorage附件文件名?

解决方案

问题根源

has_one_attached :file 并未在Upload模型上直接创建名为file的Active Record关联,而是生成了两个底层关联:file_attachment(对应ActiveStorage::Attachment)和file_blob(对应ActiveStorage::Blob)。文件名存储在Blob的filename字段中,必须通过这两层关联构建搜索条件。

步骤1:修正Upload模型的可搜索配置

修改upload.rb,指定正确的可搜索关联,并声明可访问的嵌套字段:

class Upload < ApplicationRecord
  has_one_attached :file

  def self.ransackable_associations(auth_object = nil)
    ["file_attachment"]
  end

  def self.ransackable_attributes(auth_object = nil)
    super + ["file_attachment_blob_filename"]
  end
end

步骤2:让ActiveStorage::Blob支持Ransack

在config/initializers/active_storage_ransack.rb(无则新建)中添加Blob的可搜索属性配置:

class ActiveStorage::Blob < ApplicationRecord
  def self.ransackable_attributes(auth_object = nil)
    ["filename", "content_type", "created_at", "id"]
  end
end

步骤3:修正视图搜索字段

将搜索字段改为指向Blob的文件名字段:

<%= f.search_field :file_attachment_blob_filename_cont, autofocus: true, placeholder: "Search by filename" %>

步骤4:优化控制器查询关联

修改控制器代码,提前加载关联避免N+1查询:

@q = Upload.ransack(params[:q])
@uploads = @q.result.includes(file_attachment: :blob)

可选:自定义Ransacker简化字段名

如果觉得嵌套字段名过长,可在Upload模型中添加自定义ransacker,简化视图调用:

class Upload < ApplicationRecord
  has_one_attached :file

  # ... 保留其他配置代码 ...

  ransacker :filename do
    Arel.sql("active_storage_blobs.filename")
  end

  def self.ransackable_attributes(auth_object = nil)
    super + ["filename"]
  end

之后视图可直接使用简化字段:

<%= f.search_field :filename_cont, autofocus: true, placeholder: "Search by filename" %>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 06:59:57