Skip to content

Fix MorphMany/MorphOne loads when the morph name equals the class name - #338

Merged
tmgbedu merged 1 commit into
mainfrom
fix/morph-many-eager-load
Oct 31, 2026
Merged

tmgbedu merged 1 commit into
mainfrom
fix/morph-many-eager-load

Conversation

@tmgbedu

@tmgbedu tmgbedu commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Problem

Lexeme.with_("media") (a MorphMany with morph name "Lexeme") raised ValueError: Could not find the record type key for the <Lexeme> class. load("media") and MorphOne failed the same way.

Root cause

MorphMany/MorphOne.get_record_key_lookup treated Registry.get_morph_name(cls) == cls.__name__ as "model not registered". But Model.__init_subclass__ registers every model with its class name as the default morph name. So every model without a morph_map alias, or mapped to its own class name, always hit the error. The guard could never catch a real missing model.

Changes

  • get_record_key_lookup returns Registry.get_morph_name(cls) as-is. morph_map aliases still take priority.
  • MorphMany/MorphOne.get_related now forward nested eagers (.with_(eagers or [])), the same way HasMany/HasOne do, so with_("media.lexeme") works.
  • ADR 055, added to the index.
  • Updated the test_morph_one case that asserted the old error. It now asserts the class-name default.

MorphTo/MorphToMany were not affected and are unchanged.

Tests

New tests/masoniteorm/sqlite/relationships/test_morph_name_equals_class_name.py: MorphMany eager load on a collection and on first(), MorphMany/MorphOne lazy load, MorphOne eager load, MorphTo eager load, and nested media.lexeme / first_medium.lexeme. Without the fix, 7 of the 8 original cases fail.

uv run pytest --ignore=tests/masoniteorm/postgres --cov: 3727 passed, coverage 92.75%.

🤖 Generated with Claude Code

get_record_key_lookup treated a morph name equal to the class name as an
unregistered model and raised ValueError, but every Model registers its
class name as the default morph name, so unaliased models could never be
eager or lazy loaded. Return the registry's morph name as-is, and forward
nested eagers in MorphMany/MorphOne.get_related.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@tmgbedu
tmgbedu merged commit a15430e into main Oct 31, 2026
10 checks passed
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.

1 participant