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

Laravel Has Many Merged Laravel Package

korridor/laravel-has-many-merged

Adds a hasManyMerged relationship to Laravel Eloquent, letting you combine several hasMany relations across models into one query-backed collection with sorting, limits, and eager loading. Ideal for unified feeds, timelines, and activity lists.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • Single, contained capability. korridor/laravel-has-many-merged contributes one relationship type (HasManyMerged) that presents N hasMany sources as a single Eloquent relation. No service provider, no config file, no facade, no global query scope, no schema change. From a governance standpoint this is the cheapest class of dependency to approve: narrow blast radius, confined to the model layer, removable without a data-migration project.
  • Does not fork the data-access path. Because it preserves Eloquent semantics — with(), whereHas, withCount, withSum, pagination, ordering, where constraints — it slots into existing controllers, API resources, and reporting queries. The alternative (hand-rolled collect()->merge()->sortBy() scattered across services, or raw UNION SQL) is exactly the duplicated, inconsistently tested logic that degrades correctness over time. The package's value is standardization, not novelty.
  • Quality signals outweigh popularity signals for this class of library. Release history shows a deliberate support cadence: Laravel 9 → 10 → 11 → 12, PHP 8.1 → 8.3, strict types in 1.0.0, PHPStan/Larastan generics in 1.0.1, and explicit aggregate plus whereHas test coverage as far back as 0.0.3. For code that sits inside the query layer, static-analysis friendliness and aggregate correctness matter more than 90 stars.
  • The bounded scope is also the hard constraint. hasMany only — no belongsToMany, no hasOne, no hasManyThrough chains, no field-level fusion (you cannot derive an effective price across two tables). Any roadmap item assuming general relational merging is out of scope and must be labeled as custom work up front, or the first engineer to hit the wall will file it as a bug.

Integration feasibility

  • Near-zero install cost. composer require, one relation method on the model, done. No infrastructure, no backfill, no environment configuration, no data migration.
  • High reversibility. Replacing a merged relation with an explicit union query or an internal helper is a localized refactor inside one model. The downside case is cheap — this is the single most important fact for a go/no-go decision.
  • Trivially verifiable. toSql() and a debug toolbar confirm the generated union within minutes. "Does it do what it says" is answered in a spike, not discovered in production.

Technical risk

Risk Likelihood Impact TPM mitigation
Single-maintainer, near-zero adoption (90 stars, 0 dependents, one primary author) Medium Medium Treat as vendored-by-default: pin the exact version, name a fork owner, budget ~1 day/quarter to review upstream activity. The codebase is small enough that forking is a realistic fallback, not a crisis.
Abandonment / framework-version gap Medium (low frequency) Medium Tie the review trigger to our framework upgrade ticket, not a calendar date. Exit criterion: no matching major-version release within 60 days of our upgrade → fork or inline.
No published benchmarks High Medium if placed on a hot path Require our own measurement on production-shaped data before this touches any endpoint with a latency SLO.
In-memory merge at scale Medium Medium–High Mandate DB-level constraints (where, whereHas, limits) plus pagination for any merged set expected to exceed roughly 10K rows. Enforce in code review, not in a wiki.
Aggregate and pagination semantics over a union Medium Medium withCount / withSum and pagination over a merged set do not always mean what a reviewer assumes (deduplication, ordering, count semantics). Per-relation test coverage is a merge gate, not a nice-to-have.
Non-standard polymorphic or custom foreign keys Low–Medium Low Confirm key naming during the spike. If it does not fit natively, that is a stop signal, not something to work around.
Misread as a general relationship-merge tool Medium Low Maintain a "supported / not supported" section in the internal conventions doc and link it from the PR template.

Net: technical risk is low; supply-chain risk is the one a TPM actually owns — and it is manageable precisely because the dependency is small, MIT-licensed, shallow, and has a clean removal path.

Key questions

  1. Where does duplicated merge logic already exist? (Owner: tech lead.) Deliverable: a ranked list of 5–10 candidate relations by frequency × user-visible impact. Without this, the adoption decision is aesthetic.
  2. What are the data volumes and latency SLOs on those candidates? (Owner: backend + data.) Row-count estimates determine which candidates require DB-side filtering before we write any code.
  3. Do any candidates use non-standard polymorphic or foreign keys, or hasManyThrough? (Owner: backend.) Decides whether the package fits natively or whether we stop.
  4. What is our written policy on single-maintainer dependencies? (Owner: TPM + engineering leadership.) Without a policy this gets re-litigated on every PR; resolve it once.
  5. Is the expected win developer time or user-facing consistency? (Owner: TPM.) Determines whether we measure hours saved or defect reduction — and therefore whether the result is defensible at review.
  6. Who owns the fork if upstream goes quiet? (Owner: TPM.) Name a person. Unnamed contingencies do not happen.

Integration Approach

Stack fit

  • Strong fit: Laravel 10–12 / PHP 8.1–8.3 applications with Eloquent models — API resources, admin panels, dashboards, activity feeds, customer timelines, and reporting endpoints, anywhere a user expects one consolidated list sourced from several tables.
  • Conditional fit: services that flatten related records for another consumer, but only if the merged shape is documented as a contract at the boundary (ordering, deduplication, and count semantics are part of the API surface, not an implementation detail).
  • Poor fit: anything write-path, event-driven, or real-time; anything requiring belongsToMany/hasOne/hasManyThrough; anything requiring derived values across tables. Say no early and in writing.
  • Framework coupling is explicit and current. Laravel 12 support shipped in 1.2.0; PHP 8.3 is tested. This is a package tracking the framework rather than lagging it — a meaningful signal for a query-layer dependency.

Migration path

  • No data migration. The relation is a query-time construct over existing tables; nothing to backfill, nothing to roll back.
  • Strangler pattern applies cleanly. Introduce hasManyMerged on one model alongside the existing hand-rolled merge, route a single non-critical read-only surface through it, compare outputs (ordering, counts, dedup) against the incumbent, then cut over. Repeat per surface.
  • Rollback is a one-line model edit plus reverting the call sites. Budget hours, not a sprint.
  • Prefer adoption where merge logic is already duplicated. The migration is cheapest where the incumbent behavior is well understood and already covered by tests — that is where the diff is provably behavior-preserving.

Compatibility

  • Eloquent-native contract. Anything consuming the model's relationship API keeps working; this is additive, not a change to existing relations.
  • Aggregates and whereHas behave differently enough to warrant explicit tests. These were fixed and covered as early as 0.0.3, but the semantics of counting and filtering across a union are the single most likely source of subtle regressions. Require per-relation test coverage.
  • Non-standard key conventions are the compatibility cliff. Polymorphic relations or custom foreign keys that do not map natively should be treated as out of scope rather than forced.
  • No PHP or Laravel version friction for teams on 10–12 / 8.1–8.3. Teams below that should not adopt; teams above should confirm a matching release exists first.

Sequencing

  1. Inventory (1 week). Produce the ranked candidate list and row-count estimates. This is the go/no-go gate — do not skip to the spike.
  2. Policy (parallel, 1 meeting). Settle the single-maintainer dependency policy and name the fork owner.
  3. Spike (2–3 days). One candidate, non-critical, read-only. Verify SQL via toSql(), confirm ordering and dedup match the incumbent, capture latency on production-shaped data.
  4. Pilot (1 sprint). Ship one user-facing surface behind the normal QA bar. Measure against whichever outcome was chosen in key question 5.
  5. Ratify (review). Write the internal convention: supported / not supported, the ~10K-row guidance, the mandatory pagination rule, and the version-pin policy.
  6. Roll out incrementally. One relation at a time, each with its own test coverage and rollback note. No big-bang consolidation of all merge logic in a single PR.

Operational Impact

Maintenance

  • Low, bounded, and mostly administrative. Expect roughly one day per quarter to review upstream activity plus the effort of a version bump at framework upgrades. There is no runtime component to operate, no cron, no queue, no cache to invalidate.
  • Pin the version exactly. Given a single maintainer and 0 public dependents, floating constraints buy nothing and risk a silent behavior change in the query layer.
  • Treat the fork as a planned option, not a last resort. The surface area is one relationship class; forking or inlining is a realistic, low-drama fallback and should be documented as such so it is not treated as a crisis if triggered.
  • Maintenance trigger is tied to our calendar, not theirs. The review happens when we upgrade Laravel or PHP. If no matching release exists within 60 days, fork or inline.

Support

  • No vendor support tier. MIT-licensed, community-maintained, single author. Internal ownership must be explicit: one named engineer for the fork, one named TPM for the dependency-policy decision.
  • Issue resolution is our problem. With 90 stars and 0 dependents, upstream issue traffic is minimal but so is the pool of people who have already hit any given edge case. Budget for reading the source — it is small enough to do so.
  • Documentation is adequate but thin. The README covers the happy path; the "not supported" list is on us to write and maintain internally.
  • Onboarding cost is near zero for anyone already fluent in Eloquent. The relation reads like a native hasMany at call sites, which is the point.

Scaling

  • The real scaling risk is the in-memory merge, not the query. Merged collections are assembled in PHP; large result sets mean memory pressure and latency that a normal hasMany would not incur.
  • Enforce DB-side constraints as a code-review rule. where, whereHas, and explicit limits must accompany any merged relation. Pagination is mandatory above roughly 10K expected rows. A wiki page will not hold this line; a PR checklist will.
  • No published benchmarks exist. Any endpoint with a latency SLO requires our own measurement on production-shaped data before merge. This is a gate, not a suggestion.
  • Aggregate queries scale differently than collection fetches. withCount and withSum over a union are cheap; hydrating the full merged set is not. Push features toward aggregates where the product only needs a number.
  • Read replicas behave as expected — this is still ordinary Eloquent query building, so existing read/write splitting and connection routing apply unchanged.

Failure modes

Failure mode Symptom Detection Response
Upstream goes quiet No release within 60 days of our framework upgrade Tracked via upgrade ticket, not a monitor Fork or inline; already-budgeted fallback
Memory/latency blowup Slow or OOM on an endpoint with a large merged set APM latency alert; load test in spike Add DB-side filters and pagination; if it still fails, replace with an explicit union query
Aggregate/count mismatch Dashboard numbers disagree with detail views Per-relation tests; cross-check in pilot Fix query constraints; do not "adjust" the number downstream
Ordering inconsistency across surfaces Same records in different orders on two screens Output comparison against incumbent during migration Standardize ordering in the relation definition, not in each controller
Silent version drift Behavior change after a routine composer update Exact version pin; lockfile review Revert the bump; re-evaluate in isolation
Scope creep into unsupported relations Engineer attempts belongsToMany or derived fields through the merged relation Code review against the conventions doc Stop; route to custom work; log as a scope gap, not a bug

Ramp-up

  • Engineering: under an hour. Any Eloquent-fluent developer can read the README, define a relation, and verify the SQL with toSql(). The generics support means static analysis stays green without extra annotations.
  • Code review: one artifact. A short conventions page — supported relations, the pagination threshold, the version-pin rule, the named fork owner — is sufficient to keep reviews consistent.
  • Product and design: a single framing. "We can ship unified views with fewer loading states and simpler APIs because the merge happens at the query layer — provided we constrain large datasets and avoid deeply nested or field-level merges." That sentence covers most roadmap conversations.
  • Stakeholder framing for the initial approval: prototype on a non-critical, read-only feature; measure either developer hours saved or defect reduction (pick one in advance); reversibility is high, so the downside case is cheap. The honest caveat is low community adoption — which is a reason to pin and name a fork owner, not a reason to block.
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.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin