activerecord-hackery/ransack · error · ArgumentError
#{value} cannot be converted to a Class
Error message
#{value} cannot be converted to a Class What it means
Polyamorous::Join#convert_to_class raises this ArgumentError when the klass argument (third argument to Polyamorous::Join.new, or the value assigned via Join#klass=) is anything other than a String, Symbol, or Class. Strings/Symbols are resolved with Kernel.const_get, so they must name a real constant. This argument is only needed for polymorphic joins (the '_of_Model_type' syntax) to pin the join to a concrete class.
Source
Thrown at lib/polyamorous/join.rb:65
when Class
if [InnerJoin, OuterJoin].include? type
type
else
raise ArgumentError, "#{type} cannot be converted to an ARel join type"
end
else
raise ArgumentError, "#{type} cannot be converted to an ARel join type"
end
end
def convert_to_class(value)
case value
when String, Symbol
Kernel.const_get(value)
when Class
value
else
raise ArgumentError, "#{value} cannot be converted to a Class"
end
end
end
end
View on GitHub (pinned to e82f6bab39)
Solutions
- Pass a Class (Person), a Symbol (:Person), or a String ('Person') as the klass argument
- If you hold a model instance, pass instance.class instead of the instance
- Check upstream data: verify polymorphic '_of_X_type' parsing in your code produces a constant name, not an arbitrary object
Example fix
# before Polyamorous::Join.new(:notable, :inner, article_instance) # => ArgumentError: #<Article:0x...> cannot be converted to a Class # after Polyamorous::Join.new(:notable, :inner, article_instance.class) # or Polyamorous::Join.new(:notable, :inner, 'Article')
Defensive patterns
Strategy: validation
Validate before calling
klass = klass.class if klass.is_a?(ActiveRecord::Base)
unless klass.is_a?(Class) || klass.is_a?(String) || klass.is_a?(Symbol)
raise ArgumentError, "klass must be a Class/String/Symbol, got #{klass.class}"
end
join = Polyamorous::Join.new(:notable, :inner, klass) Type guard
def join_klass_candidate?(value) value.is_a?(Class) || value.is_a?(String) || value.is_a?(Symbol) end
Try / catch
begin
join.klass = klass_value
rescue ArgumentError, NameError => e
Rails.logger.error("Invalid join klass #{klass_value.inspect}: #{e.message}")
raise
end Prevention
- Never pass model instances as the klass argument — pass instance.class
- If klass comes from params (polymorphic _of_X_type), validate it against your model list before const_get
- Watch for NameError from Kernel.const_get on string klasses — invalid names fail there before this check
When it happens
Trigger: Polyamorous::Join.new(:notable, :inner, 42), Join.new(:notable, :inner, nil_via_hash_explosion), or join.klass = some_object_instance. Also raised indirectly when a malformed polymorphic association string yields a non-class value that gets forwarded as klass.
Common situations: Building polymorphic joins by hand and passing a model instance instead of its class; passing a Hash of options where the class is expected; a nil or integer leaking in from params or config when constructing custom join trees.
Understand the failure class
Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.
Related errors
- #{type} cannot be converted to an ARel join type
- Don't know how to klassify #{obj}
- Don't know what context to use for #{object}
- No Ransack::Search object was provided to #{method_name}!
- Invalid argument (#{args.class}) supplied to attributes=
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/a095d5a0b78dcbe4.
Report an issue: GitHub.