ActiveStorage::Attachment & Ransack

Jan 01, 2024

I ran into this error earlier today:

ActionView::Template::Error (Ransack needs ActiveStorage::Attachment attributes explicitly allowlisted as
searchable. Define a ransackable_attributes class method in your ActiveStorage::Attachment
model, watching out for items you DONT want searchable (for
example, encrypted_password, password_reset_token, owner or
other sensitive information). You can use the following as a base:

class ActiveStorage::Attachment < ApplicationRecord

  # ...

  def self.ransackable_attributes(auth_object = nil)
    ["blob_id", "created_at", "id", "id_value", "name", "record_id", "record_type"]
  end

  # ...

end
):
    1: # frozen_string_literal: true
    2: insert_tag renderer_for(:index)

ransack (4.1.1) lib/ransack/adapters/active_record/base.rb:112:in `deprecated_ransackable_list'
ransack (4.1.1) lib/ransack/adapters/active_record/base.rb:38:in `ransackable_attributes'
ransack (4.1.1) lib/ransack/context.rb:159:in `ransackable_attribute?'
ransack (4.1.1) lib/ransack/adapters/active_record/context.rb:67:in `attribute_method?'
ransack (4.1.1) lib/ransack/adapters/active_record/context.rb:78:in `attribute_method?'
(...)

Seems like this was happening because ransack requires an explicit list of attributes that can be searched.

How to fix

First, monkeypatch ActiveStorage::Attachment like so:

ext/active_storage/ransackable_attachment.rb:

module RansackableAttachment
  def ransackable_attributes(_auth_object = nil)
    %w[blob_id created_at id id_value name record_id record_type]
  end
end

ActiveSupport.on_load(:active_storage_attachment) do
  ActiveStorage::Attachment.extend RansackableAttachment
end

Then in config/application.rb:

module MyRailsApp
  class Application < Rails.Application
    [...]
    Rails.configuration.to_prepare do
      require_relative '../ext/active_storage/ransackable_attachment'
    end
  end
end