activerecord-hackery/ransack · error · ArgumentError

Don't know how to klassify #{obj}

Error message

Don't know how to klassify #{obj}

What it means

Ransack's ActiveRecord adapter raises this ArgumentError from Context#klassify when it is handed an object it cannot reduce to an ActiveRecord model class: it accepts an AR::Base subclass directly, anything responding to #klass (associations, relations), or anything responding to #base_klass (join dependency parts). This method sits on the traverse path, so it fires while Ransack resolves an association chain to a concrete class.

Source

Thrown at lib/ransack/adapters/active_record/context.rb:101

              end
            end
          end
          exists
        end

        def table_for(parent)
          parent.table
        end

        def klassify(obj)
          if Class === obj && ::ActiveRecord::Base > obj
            obj
          elsif obj.respond_to? :klass
            obj.klass
          elsif obj.respond_to? :base_klass
            obj.base_klass
          else
            raise ArgumentError, "Don't know how to klassify #{obj}"
          end
        end

        # All dependent Arel::Join nodes used in the search query.
        #
        # This could otherwise be done as `@object.arel.join_sources`, except
        # that ActiveRecord's build_joins sets up its own JoinDependency.
        # This extracts what we need to access the joins using our existing
        # JoinDependency to track table aliases.
        #
        def join_sources
          base, joins = begin
            alias_tracker = @object.alias_tracker
            constraints   = @join_dependency.join_constraints(@object.joins_values, alias_tracker, @object.references_values)

            [
              Arel::SelectManager.new(@object.table),
              constraints

View on GitHub (pinned to e82f6bab39)

Solutions

  1. Verify the association chain you are searching targets a real ActiveRecord model (check MyClass < ActiveRecord::Base)
  2. For polymorphic associations, use the '_of_Model_type' form with a valid AR model name, e.g. q[notable_of_Article_type_name_cont]
  3. If the class name in the suffix is misspelled, fix it — unpolymorphize_association resolves it via Kernel.const_get before klassify sees it
  4. Search a concrete association instead of the polymorphic one (e.g. go through a has_many through)

Example fix

# before (params)
q = { 'notable_name_cont' => 'foo' }  # polymorphic, no concrete class
Person.ransack!(q)

# after
q = { 'notable_of_Article_type_title_cont' => 'foo' }
Person.ransack!(q)
Defensive patterns

Strategy: validation

Validate before calling

# before searching a polymorphic chain, verify the target resolves to an AR model
assoc_klass = Person.reflect_on_association(:notable)&.klass
polymorphic = Person.reflect_on_association(:notable)&.polymorphic?
raise ArgumentError, 'cannot search polymorphic notable directly' if polymorphic

# for _of_X_type params, validate X is one of your AR models:
allowed = %w[Article Comment].freeze
param_class = params[:q].to_s[/notable_of_(\w+)_type/, 1]
return if param_class && !allowed.include?(param_class)

Type guard

def ar_model?(obj)
  obj.is_a?(Class) && obj < ActiveRecord::Base
end

def klassifiable?(obj)
  ar_model?(obj) || obj.respond_to?(:klass) || obj.respond_to?(:base_klass)
end

Try / catch

begin
  Person.ransack!(params[:q]).result
rescue ArgumentError, Ransack::InvalidSearchError => e
  Rails.logger.info("Unsearchable association chain: #{e.message}")
  Person.all # degrade gracefully
end

Prevention

When it happens

Trigger: Searching a polymorphic association with a '_of_Model_type' suffix where Model is not an ActiveRecord::Base subclass (e.g. notable_of_NotAModel_type, or a class name that resolves to a PORO/mongo object); traversing an association whose reflection target does not expose klass/base_klass (non-AR association types, some composite-key gems).

Common situations: Trying to search polymorphic belongs_to associations directly, which Ransack does not support without the explicit _of_Class_type disambiguation; a typo'd class name in the _of_ suffix (Kernel.const_get resolves it to something unexpected); associations defined by gems that break the reflection contract after a Rails upgrade.

Related errors


AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21). Data as JSON: /api/errors/7881c29851d7e968. Report an issue: GitHub.