Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Improved Polymorphic Eloquent Builder Laravel Package

rapidwebltd/improved-polymorphic-eloquent-builder

Improve polymorphic relationship querying in Laravel with a cleaner Eloquent builder API. This package helps you filter and chain queries across morph types more expressively, reducing boilerplate when working with polymorphic models.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What the package is. rapidwebltd/improved-polymorphic-eloquent-builder is a thin extension of Laravel's Eloquent query builder targeting polymorphic relations. It swaps a model's builder (via a trait / newEloquentBuilder override) so that queries against the child side of a morphTo/morphMany relationship are automatically constrained by the parent's morph type, and adds helper methods for scoping by morphable class. In practice it is a few hundred lines of where-clause composition around morph_type / morph_id columns.

Architecture fit. Structurally it is a low-coupling, model-layer concern. It does not touch the container, routing, or service providers, and it does not impose a persistence model. That is architecturally clean — the concern is real (polymorphic queries silently returning cross-type rows is a genuine correctness and data-isolation hazard), and the placement is correct.

Integration feasibility. Weak on any current stack. The last release is 2018-01-30, which places it in the Laravel 5.5/5.6 and PHP 7.0/7.1 era. On Laravel 9/10/11/12 and PHP 8.1+, composer require will fail on platform constraints; forcing it with --ignore-platform-reqs will likely produce runtime breakage, because the Eloquent Builder has accumulated new methods, changed return types, and internal call paths. Adoption is also negligible (11 stars), so there is no implicit field-testing from a user base.

Technical risk.

Risk Severity Notes
Abandonment High No release in 7+ years; assume unmaintained from day one.
Framework drift High Builder subclassing is one of the more brittle extension points across Laravel majors.
Builder collision Medium Only one custom builder per model. Conflicts with Scout, search packages, soft-delete extensions, or our own base builder.
Licensing Medium LGPL-3.0 is unusual for PHP libraries; the relinking analysis is murky for interpreted, source-distributed code. Requires legal sign-off, not an engineering call.
Morph map mismatch Medium If we use Relation::morphMap(), stored types are aliases, not FQCNs. Code written pre-morph-map may compare against class names and silently match nothing — a null-result bug, not an error.
Feature erosion High Laravel 5.8+ shipped whereHasMorph, whereMorphedTo, and morphWith, which cover much of the original gap.

Key questions to resolve before any spend.

  1. What is the concrete failing behaviour on our current Laravel version? Write the failing test first.
  2. Does native whereHasMorph / whereMorphedTo / morphWith already solve it? If yes, the package is unnecessary.
  3. If not, is the total logic small enough to reimplement internally as a first-party trait (likely 50–150 lines)? Vendoring is almost always cheaper than owning an abandoned dependency.
  4. Has legal reviewed LGPL-3.0 for our distribution model?
  5. Do we use morphMap, and if so does the package's type comparison survive it?

Integration Approach

Stack fit. Viable only on a legacy Laravel 5.x application, and even there only if we accept that we are forking. On Laravel 8+ the honest answer is: not compatible, do not attempt.

Recommended path (in order of preference).

  1. Reimplement internally. Use the package as a reference implementation, not a dependency. Read the source, extract the constraint logic, write it as an in-house trait with tests against our actual schema and morph map. This eliminates the license question, the abandonment risk, and the version lock in one move.
  2. Vendor/fork with a hard ownership marker. Pin to a specific commit in a private VCS, rename the namespace, add a README explaining why the fork exists and who owns it, and add a regression suite covering the exact polymorphic queries we rely on.
  3. Adopt as-is only in a legacy app that is already frozen on Laravel 5.x, has no upgrade roadmap, and where legal has cleared LGPL. Even then, pin exactly and treat it as unmaintained.

Migration and compatibility notes.

  • Do not run this alongside any other custom Eloquent builder. Audit newEloquentBuilder overrides across the codebase first.
  • Verify the composite index (morph_type_column, morph_id_column) exists on every polymorphic table before turning on type-scoped queries; the package changes query shape and will expose missing indexes.
  • Normalise on Relation::morphMap() at the same time, otherwise the type comparison it performs may be based on the wrong value.

Sequencing.

  1. Reproduce the concrete bug with a failing test on our stack (1–2 days).
  2. Evaluate native Laravel alternatives against that test (1–2 days).
  3. If native fails, write the internal trait (2–4 days incl. tests).
  4. Code review, legal check, document the decision in an ADR.
  5. Delete the dependency candidate from the backlog.

Total realistic cost: under two weeks. That is the number to put against the "just composer require it" instinct.

Operational Impact

Maintenance. The real cost is not integration, it is ownership. There is no upstream to patch a PHP 9 or Laravel 13 incompatibility, no security response, and issue triage is effectively dead. If we adopt it, we are the maintainers from day one — budget accordingly, or avoid the transfer of liability entirely by reimplementing.

Supportability. No vendor support, negligible community. A new engineer encountering a custom builder subclass will lose time determining whether a query's constraints come from the framework or from a 2018 package. That is a recurring, low-grade tax on every polymorphic query debug session — worse than a one-time integration cost.

Scaling. The package itself has no meaningful scaling profile: it emits WHERE predicates. Two things matter instead. First, index coverage — a missing (type, id) composite index turns type-scoped polymorphic lookups into table scans, and polymorphic tables are exactly the ones that grow fastest (comments, activities, attachments, audit rows). Second, query shape stability: if the constraint is ever not applied, the query silently widens. That is a correctness and performance cliff at once.

Failure modes to monitor.

  • Silent over-fetch — the type constraint fails to apply and queries return rows belonging to other parent types. This is a cross-entity data-leak class of bug, not just a display bug. Highest severity.
  • Silent under-fetch — morph-map alias vs. FQCN mismatch yields empty result sets with no error. Presents as "data disappeared" and burns support time.
  • Builder collision — another package's builder wins the newEloquentBuilder race; behaviour becomes load-order dependent.
  • Upgrade breakage — a PHP or Laravel bump fails after the code is load-bearing.

Mitigation: assert the constraint in tests at the query level (assert generated SQL / toSql()), not just at the result level; alert on unexpected row volumes from polymorphic endpoints.

Ramp-up. The concept is learnable in an hour for anyone who knows Eloquent; the institutional ramp-up is the problem. Engineers must learn (a) that the package exists, (b) why it was added, and (c) that it is unforked and unpatched. That knowledge lives in one or two heads unless it is written down. If we proceed, an ADR plus a short inline comment at the trait's usage sites is mandatory, not optional.

Recommendation. Treat this as a reference implementation, not a dependency. The problem it addresses is legitimate; the artifact is seven years stale, low-adoption, copyleft-licensed, and largely superseded by first-party Laravel APIs. Reimplement the constraint logic in-house in under a sprint, and close the ticket with an ADR recording why we did not adopt it.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin