Fix table prefix duplication in multi-level model inheritance#2353
Merged
glennjacobs merged 1 commit intolunarphp:1.xfrom Dec 8, 2025
Merged
Fix table prefix duplication in multi-level model inheritance#2353glennjacobs merged 1 commit intolunarphp:1.xfrom
glennjacobs merged 1 commit intolunarphp:1.xfrom
Conversation
When extending a model multiple times (e.g., CustomProduct extends Product extends BaseModel), the table prefix was being applied multiple times, resulting in table names like "lunar_lunar_products" instead of "lunar_products". **Problem:** The `HasModelExtending::getTable()` method instantiated parent classes recursively with `(new $parentClass)->table`, causing the BaseModel constructor to apply the prefix at each inheritance level. **Solution:** - Added `resolveRootModelClass()` to find the root Lunar model in the inheritance chain - Added `resolveBaseTableName()` to get the base table name using reflection without triggering the constructor - Modified `getTable()` to resolve the root model and apply the prefix only once **Test Coverage:** Added test case for multi-level inheritance to ensure prefix is not duplicated across multiple levels of model extension.
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a bug where table prefixes were duplicated in multi-level model inheritance scenarios (e.g., lunar_lunar_products instead of lunar_products). The issue occurred because each inheritance level triggered the BaseModel constructor, reapplying the prefix. The solution uses reflection to traverse the inheritance chain to the root Lunar model and applies the prefix only once.
Key changes:
- Refactored
getTable()to resolve the root model class and apply prefix once - Added helper methods to traverse inheritance chain and extract base table name without triggering constructors
- Added test coverage for multi-level inheritance scenarios
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
packages/core/src/Base/Traits/HasModelExtending.php |
Refactored getTable() method and added resolveRootModelClass() and resolveBaseTableName() helper methods to prevent prefix duplication |
tests/core/Stubs/Models/Custom/DeepCustomProduct.php |
Added stub model for testing three-level inheritance chain |
tests/core/Unit/Base/Traits/HasModelExtendingTest.php |
Added test case to verify correct table naming across multiple inheritance levels |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
When extending a model multiple times (e.g., CustomProduct extends Product extends BaseModel), the table prefix was being applied multiple times, resulting in table names like "lunar_lunar_products" instead of "lunar_products".
Problem:
The
HasModelExtending::getTable()method instantiated parent classes recursively with(new $parentClass)->table, causing the BaseModel constructor to apply the prefix at each inheritance level.Solution:
resolveRootModelClass()to find the root Lunar model in the inheritance chainresolveBaseTableName()to get the base table name using reflection without triggering the constructorgetTable()to resolve the root model and apply the prefix only onceTest Coverage:
Added test case for multi-level inheritance to ensure prefix is not duplicated across multiple levels of model extension.