Skip to content

Treat an unknown polymorphic type as an invalid search key - #1741

Merged
scarroll32 merged 2 commits into
mainfrom
unknown-polymorphic-type-invalid
Oct 8, 2026
Merged

scarroll32 merged 2 commits into
mainfrom
unknown-polymorphic-type-invalid

Conversation

@scarroll32

@scarroll32 scarroll32 commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Note

This PR was opened by Claude (Claude Code), acting on behalf of @scarroll32.

Reported in #1738, an agent-filed issue that was deleted from the tracker shortly after this PR was opened, so the reference no longer resolves. The bug was reproduced independently and the fix stands on its own.

The bug

The class in an _of_Model_type suffix was resolved with Kernel.const_get, straight from the query string. Four kinds of input raised instead of following ignore_unknown_conditions:

key raised
notable_of_NoSuchType_type_name_eq NameError: uninitialized constant NoSuchType
notable_of_person_type_name_eq NameError: wrong constant name person
notable_of_String_type_name_eq (a module likewise) ArgumentError: Don't know how to klassify String
notable_of_ApplicationRecord_type_name_eq (abstract) ActiveRecord::TableNotSpecified
notable_of_ENV::Person_type_name_eq (namespace that is not a module) TypeError: ENV::Person does not refer to class/module

The issue reports the first. The others fall out of the same lookup; the last was found by Copilot's review of this PR.

The fix

Context#unpolymorphize_association resolves the name with safe_constantize and accepts only a concrete model, through a new searchable_class? hook on the context: by default the class must have ransackable_attributes; the Active Record context requires a non-abstract ActiveRecord::Base subclass. Any other suffix is not a polymorphic reference, so the key is treated like any unknown attribute: ignored by default, InvalidSearchError in a strict search. A sort on such a key follows the same rule.

Specs cover all eight shapes under both settings, and a sort on an unknown type and on a non-module namespace. The docs' polymorphic page gets a paragraph and a note.

Suite: 802 examples, 0 failures on Rails 8.1 and 7.2.2.1 (SQLite) and on PostgreSQL; RuboCop clean.

Worth a backport to 5-0-stable? A crafted query string currently produces a 500 from NameError. There is no resource exhaustion, so I have not treated it as an advisory.

🤖 Generated with Claude Code

The class in an `_of_Model_type` suffix was resolved with
`Kernel.const_get`, which raises `NameError` for a name that is not a
constant, or is lowercase, straight from the query string, whatever
`ignore_unknown_conditions` is set to. A constant that is not a model
(`String`, a module, an abstract class, `ActiveRecord::Base` itself) got
past the lookup and raised from `klassify` or the schema instead.

Resolve the name with `safe_constantize` and accept only a concrete
model, through a new `searchable_class?` hook on the context that the
Active Record integration refines. Any other suffix is not a polymorphic
reference, so the key is ignored by default and raises
`InvalidSearchError` in a strict search, like any unknown attribute.

Fixes #1738

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Non-module namespace components still raise an unhandled TypeError, bypassing unknown-key handling.

1 open finding
What changed in this PR

Routes invalid polymorphic type suffixes through Ransack’s existing unknown-key handling.

Changes:

  • Adds safe constant resolution and model validation.
  • Tests invalid conditions and sorts in default and strict modes.
  • Documents the updated behavior.
File Description
spec/​ransack/​search_spec.rb Adds invalid-type regression coverage.
lib/​ransack/​context.rb Resolves and validates polymorphic types.
lib/​ransack/​active_record/​context.rb Restricts types to concrete Active Record models.
docs/​going-further/​polymorphic-search.md Explains invalid-type handling.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread lib/ransack/context.rb
`safe_constantize` swallows a missing constant but not a namespace that
is not a module: `"ENV::Person".safe_constantize` raises `TypeError`, so
`notable_of_ENV::Person_type_name_eq` still raised from the query string.
Treat it like every other non-model suffix. Found by Copilot review.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@scarroll32
scarroll32 merged commit 8aedd8f into main Oct 8, 2026
29 checks passed
@scarroll32
scarroll32 deleted the unknown-polymorphic-type-invalid branch October 8, 2026 19:34
@scarroll32 scarroll32 mentioned this pull request Oct 9, 2026
61 tasks done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants