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

  1. Pass a Class (Person), a Symbol (:Person), or a String ('Person') as the klass argument
  2. If you hold a model instance, pass instance.class instead of the instance
  3. 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

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


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