activerecord-hackery/ransack · error · ArgumentError
#{type} cannot be converted to an ARel join type
Error message
#{type} cannot be converted to an ARel join type What it means
Polyamorous (Ransack's join-handling subsystem) raises this ArgumentError when a join type is given as a Class that is not one of the two accepted Arel join node classes (Polyamorous::InnerJoin / Polyamorous::OuterJoin). The join type for Polyamorous::Join must be 'inner'/:inner, 'outer'/:outer, or one of those exact classes. Any other Class (for example a raw Arel::Nodes::InnerJoin or a custom join class) is rejected by convert_to_arel_join_type.
Source
Thrown at lib/polyamorous/join.rb:51
alias :== :eql?
def add_to_tree(hash)
hash[self] ||= {}
end
private
def convert_to_arel_join_type(type)
case type
when 'inner', :inner
InnerJoin
when 'outer', :outer
OuterJoin
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
endView on GitHub (pinned to e82f6bab39)
Solutions
- Pass one of the accepted values: :inner, :outer, 'inner', or 'outer' — e.g. Polyamorous::Join.new(:articles, :outer)
- If you need the class form, use Polyamorous::InnerJoin or Polyamorous::OuterJoin exactly — they are the only whitelisted classes
- If you were passing Arel::Nodes::InnerJoin/Arel::Nodes::OuterJoin, replace them with the Polyamorous constants (which alias the correct nodes for your Rails version)
- Remove custom join classes and express the join via Ransack's normal association-name + join_type API
Example fix
# before join = Polyamorous::Join.new(:articles, Arel::Nodes::InnerJoin) # => ArgumentError: Arel::Nodes::InnerJoin cannot be converted to an ARel join type # after join = Polyamorous::Join.new(:articles, Polyamorous::InnerJoin) # or simply join = Polyamorous::Join.new(:articles, :inner)
Defensive patterns
Strategy: validation
Validate before calling
VALID_JOIN_TYPES = [Polyamorous::InnerJoin, Polyamorous::OuterJoin].freeze
def valid_join_type?(type)
%w[inner outer].include?(type.to_s) || VALID_JOIN_TYPES.include?(type)
end
# before constructing:
raise ArgumentError, "bad join type: #{type}" unless valid_join_type?(type)
join = Polyamorous::Join.new(:articles, type) Type guard
def polyamorous_join_type?(type) case type when 'inner', :inner, 'outer', :outer then true when Class then [Polyamorous::InnerJoin, Polyamorous::OuterJoin].include?(type) else false end end
Try / catch
begin
join = Polyamorous::Join.new(:articles, type)
rescue ArgumentError => e
Rails.logger.warn("Falling back to inner join: #{e.message}")
join = Polyamorous::Join.new(:articles, :inner)
end Prevention
- Standardize on the symbols :inner/:outer everywhere in your codebase; never pass raw Arel node classes
- If join types come from config or params, whitelist them against %w[inner outer] before use
- Add a spec asserting your custom join-building code only emits the two accepted values
When it happens
Trigger: Polyamorous::Join.new(:articles, SomeJoinClass) or Polyamorous::Join#type=(SomeJoinClass) where SomeJoinClass is not Polyamorous::InnerJoin/OuterJoin. Typical case: passing Arel::Nodes::InnerJoin (the Arel node class itself) instead of the Polyamorous alias, or a custom join class from code written against an older Polyamorous API.
Common situations: Upgrading Ransack/Polyamorous after the join-type API was narrowed to the two Arel node classes; copy-pasted custom join code from old blog posts that passes Arel node classes; monkey-patches or custom adapters that build Join objects with their own join class hierarchy.
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
- #{value} cannot be converted to a Class
- Don't know what context to use for #{object}
- Don't know how to klassify #{obj}
- Don't know how to klassify #{obj.inspect}
- No Ransack::Search object was provided to #{method_name}!
AI-assisted analysis of activerecord-hackery/ransack@e82f6bab39 (2026-08-21).
Data as JSON: /api/errors/ca3488db7ab8358f.
Report an issue: GitHub.