MONGOID-5936 Resolve polymorphic *_type via the association resolver in eager loader#6146
Open
comandeo-mongo wants to merge 2 commits into
Open
Conversation
…in eager loader
The non-eager polymorphic accessor goes through `association.resolver.model_for(key)`
(`accessors.rb:43-44`), which raises `UnrecognizedModelAlias` for any value that is
not registered with the configured resolver. The eager loader bypassed this and
called `Object.const_get(type)` directly on the user-controlled `*_type` field,
producing two inconsistencies with the non-eager path:
* For applications using a custom `Mongoid::ModelResolver` to allowlist
polymorphic types, eager loading would still resolve any constant by name,
including aliases that `const_get` cannot find ("dept" -> NameError) and
classes that the resolver does not allow.
* For values that resolve to non-Document constants (e.g. "Kernel"), the eager
path would later fail with `NoMethodError` instead of the documented
`UnrecognizedModelAlias`.
Replace `Object.const_get(type)` with `@association.resolver.model_for(type)`
so the eager and non-eager paths share the same allowlist.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR aligns polymorphic belongs_to eager-loading behavior with the non-eager accessor by resolving the user-controlled *_type value through the association’s configured Mongoid::ModelResolver, ensuring consistent allowlisting and error semantics.
Changes:
- Route polymorphic eager-loader type resolution through
@association.resolver.model_for(type)instead ofObject.const_get(type). - Add a spec asserting eager loading raises
Mongoid::Errors::UnrecognizedModelAliasfor unregistered*_typevalues. - Add an integration spec asserting eager loading correctly resolves alias-based
*_typevalues across resolver configurations.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| lib/mongoid/association/referenced/belongs_to/eager.rb | Uses the association resolver for polymorphic *_type resolution during eager loading (consistent error contract & allowlist). |
| spec/mongoid/association/referenced/belongs_to/eager_spec.rb | Adds coverage for eager-loading raising UnrecognizedModelAlias on tampered/unregistered *_type. |
| spec/integration/associations/belongs_to_spec.rb | Adds coverage for eager-loading resolving alternate alias values for polymorphic associations. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jamis
approved these changes
Jun 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
MONGOID-5936
The non-eager polymorphic accessor at
lib/mongoid/association/accessors.rb:43-44goes throughassociation.resolver.model_for(key)and raisesUnrecognizedModelAliasfor any value that is not registered with the configured resolver. The eager loader bypassed this and calledObject.const_get(type)directly on the user-controlled*_typefield atlib/mongoid/association/referenced/belongs_to/eager.rb:30. Two inconsistencies followed:Mongoid::ModelResolverhad no protection on the eager path. Aliases thatconst_getcannot resolve (e.g."sandbox_dept") raisedNameError, and any class name resolvable byconst_getwas loaded regardless of whether it was registered with the resolver."Kernel") caused a laterNoMethodErrorinstead of the documentedMongoid::Errors::UnrecognizedModelAlias.This change routes the polymorphic type lookup through
@association.resolver.model_for(type)so the eager and non-eager paths share the same allowlist and the same error contract.Test plan
spec/mongoid/association/referenced/belongs_to/eager_spec.rb— eager loading raisesUnrecognizedModelAliaswhen*_typereferences a constant that is not registered with the resolver.spec/integration/associations/belongs_to_spec.rb— eager loading correctly resolves alias-based*_typevalues across the default, registered, and unregistered resolver configurations.bundle exec rubocopclean on changed files.spec/mongoid/association/referenced/,spec/mongoid/association/eager_spec.rb, andspec/mongoid/model_resolver_spec.rbsuites pass against a local replica set (3485 examples, 0 failures).