activerecord-hackery/ransack · error · ArgumentError
Don't know how to klassify #{obj.inspect}
Error message
Don't know how to klassify #{obj.inspect} What it means
The base Ransack::Context#klassify (unlike the ActiveRecord adapter version, which also accepts objects responding to base_klass) raises this ArgumentError when given an object that is neither an ActiveRecord::Base subclass nor responds to #klass. It is reached via Context#traverse while resolving an association/attribute path string to a model class during search building.
Source
Thrown at lib/ransack/context.rb:65
@base = @join_dependency.instance_variable_get(:@join_root)
end
def bind_pair_for(key)
@bind_pairs ||= {}
@bind_pairs[key] ||= begin
parent, attr_name = get_parent_and_attribute_name(key.to_s)
[parent, attr_name] if parent && attr_name
end
end
def klassify(obj)
if Class === obj && ::ActiveRecord::Base > obj
obj
elsif obj.respond_to? :klass
obj.klass
else
raise ArgumentError, "Don't know how to klassify #{obj.inspect}"
end
end
# Convert a string representing a chain of associations and an attribute
# into the attribute itself
def contextualize(str)
parent, attr_name = bind_pair_for(str)
table_for(parent)[attr_name]
end
def chain_scope(scope, args)
return unless @klass.method(scope) && args != false
@object = if scope_arity(scope) < 1 && args == true
@object.public_send(scope)
elsif scope_arity(scope) == 1 && args.is_a?(Array)
# For scopes with arity 1, pass the array as a single argument instead of splatting
@object.public_send(scope, args)
elseView on GitHub (pinned to e82f6bab39)
Solutions
- Ensure every association in the searched chain is a standard ActiveRecord association pointing at an AR model
- If you maintain a custom adapter, implement klassify to handle your join objects (mirror the base_klass fallback the AR adapter has)
- Update ransack to a version matching your Rails version — join node internals (klass vs base_klass) shifted across Rails 5.x/6.x/7.x
Defensive patterns
Strategy: validation
Validate before calling
# before calling traverse/klassify paths with a custom base:
def klassifiable_base?(obj)
(obj.is_a?(Class) && obj < ActiveRecord::Base) || obj.respond_to?(:klass)
end
raise ArgumentError, "cannot traverse from #{obj.inspect}" unless klassifiable_base?(obj) Type guard
def klassifiable?(obj) (obj.is_a?(Class) && obj < ActiveRecord::Base) || obj.respond_to?(:klass) end
Try / catch
begin
context.traverse(assoc_path)
rescue ArgumentError => e
Rails.logger.warn("Skipping untraversable path #{assoc_path}: #{e.message}")
nil
end Prevention
- Pin the ransack version to one tested against your Rails release — klassify depends on join-node internals (klass vs base_klass)
- Keep association chains inside standard ActiveRecord reflections; avoid mixing custom join objects into Ransack contexts
- If you subclass Ransack::Context, mirror the ActiveRecord adapter's klassify fallbacks (klass, then base_klass)
When it happens
Trigger: Ransack resolves a path like 'parent_children_grandchildren_attr' and an intermediate segment resolves to an object without #klass — e.g. a join dependency node from a mismatched Rails version, or a custom object injected into the traversal base. Also reachable by calling context.klassify(obj) directly with a plain object.
Common situations: Rails version incompatibilities where JoinDependency internals no longer expose klass on join nodes (the AR adapter's base_klass branch exists precisely for this); custom Ransack adapters; searching associations backed by non-AR classes.
Related errors
- Don't know how to klassify #{obj}
- #{type} cannot be converted to an ARel join type
- Don't know what context to use for #{object}
- A context is required to translate associations
- #{value} cannot be converted to a Class
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/45db10084f0c43d8.
Report an issue: GitHub.