Elasticsearch重建ActiveStorage图片索引时报stack level too deep错误
错误原因
Searchkick 执行重建索引时,默认会调用模型的 as_json 方法将所有属性和关联序列化为 JSON 格式存入 Elasticsearch。当模型关联了 has_many_attached :images 这类 ActiveStorage 关联时,ActiveStorage 生成的关联代理对象内部存在和 ActiveRecord 上下文的循环引用,序列化过程中会触发无限递归调用,最终导致栈溢出错误。你提供的报错栈最终停在 as_json 调用逻辑,也完全符合这个触发条件。
解决方案
根据你是否需要索引图片相关信息,可以选择对应的修复方案:
- 方案1:不需要索引图片信息(绝大多数场景)
自定义search_data方法,仅声明你实际需要参与搜索、过滤的字段,完全排除 images 关联:class Product < ApplicationRecord has_many_attached :images searchkick # 自定义索引字段,避免引入不必要的关联对象 def search_data { id: id, name: name, description: description, price: price # 其他需要索引的业务字段自行补充 } end end - 方案2:需要索引图片的部分信息
如果需要把图片的文件名、访问地址等信息存入索引,仅提取需要的纯文本/数值字段,不要直接把整个ActiveStorage::Attachment关联对象放入索引:class Product < ApplicationRecord has_many_attached :images searchkick def search_data base_attrs = attributes.slice("id", "name", "description", "price") base_attrs.merge( image_filenames: images.pluck(:filename), image_urls: images.map { |img| Rails.application.routes.url_helpers.rails_blob_path(img, only_path: true) } ) end end
修改完成后重新执行 rake searchkick:reindex CLASS=Product 即可正常完成索引重建。
内容的提问来源于stack exchange,提问作者sufyan iqbal
相关产品推荐
相关产品推荐

