biiiiiigmonster/hasin
biiiiiigmonster/hasin brings recursive "has in" relationship queries to Laravel's Eloquent ORM, letting you fetch ancestors, descendants, and other nested tree data with fluent, hasMany-style syntax instead of raw recursive SQL. Ideal for category trees, comment threads, and org charts.
Architecture fit
biiiiiigmonster/hasin is a focused query-layer package: it provides whereHasIn / orWhereHasIn / whereDoesntHaveIn-style methods that rewrite Eloquent's correlated exists (...) subqueries into where ... in (select ...) form. It is additive to Eloquent, not a replacement for it — no service provider rewiring of the ORM, no persistence or schema changes.has/whereHas on a related table and the correlated EXISTS plan is the bottleneck (e.g., list endpoints over millions of rows with a selective relationship). It is a poor fit for code paths where the subquery result set is large or non-selective, where the optimizer already rewrites the EXISTS well, or where we depend on whereHas's ability to pass a closure that adds ordering/limits/aggregates to the inner query — IN semantics do not compose identically.Integration feasibility
EXPLAIN on production-shaped data, plus a correctness test proving row parity with the whereHas it replaces. Budget engineer-days per batch of call sites, not per install.Technical risk
laravel-shift compatibility PR landed, then the maintainer immediately followed with a fix(): l13 compatibility commit. That strongly implies the automated port was insufficient and real behavior needed patching. Green CI on the maintainer's matrix is not evidence that our query shapes still produce identical SQL.IN (subquery) and EXISTS (subquery) are equivalent for these predicates in standard SQL, but they are not guaranteed to be equivalent in the presence of NULL handling in the correlation, global scopes applied asymmetrically, soft deletes, or polymorphic relations. Silent row-count differences are the failure mode to test for explicitly.EXISTS as a semi-join. Treat the package as a candidate optimization, not an upgrade.Key questions
composer.json constraints in v5.1.0 — minimum PHP and the supported Laravel range? Does adding it force a PHP or framework floor above our current baseline?laravel-shift "l13 compatibility" fix change, and does it alter generated SQL for any existing query shape?whereHas-bound, and what did EXPLAIN show? Do we have evidence the rewrite helps before we adopt?whereHas usages pass closures with orderBy/limit/aggregates, which may not translate faithfully?Stack fit
IN (subquery) planning; behavior and gains differ by engine (MySQL vs PostgreSQL vs SQLite), so validation must happen against the engine we actually run in production, not the test container.Migration path
whereHas in place; introduce whereHasIn only at call sites where a measured problem exists. This yields a per-endpoint rollback (revert the query builder line) rather than a package-level rollback.Compatibility
^5.1.0 and let Composer resolve within the major. Stay on 5.x; do not straddle majors across services.Sequencing
whereHas-heavy read endpoints. Capture baseline query plans and p95 latency.Maintenance
Support
Scaling
IN list itself becomes a cost, so the benefit curve is not monotonic — expect wins on some endpoints and neutral-or-worse on others, and let measurement decide.Failure modes
whereHasIn returns a different row set than the whereHas it replaced, typically around soft deletes, polymorphic relations, or NULL correlation. Highest severity, lowest detectability. Mitigated by parity tests on representative data.Ramp-up
whereHas, so the learning is in knowing when to use it, not how. Half a day of documentation and one worked example should be enough for a mid-level developer.EXPLAIN and judging selectivity. If the team lacks that, adoption will be cargo-cult and the wins will be unverifiable. Budget for a short pairing session with whoever owns database performance rather than formal training.How can I help you explore Laravel packages today?