kirschbaum-development/eloquent-power-joins
Eloquent Power Joins brings Laravel-style joins to Eloquent. Join via relationship definitions, reuse model scopes in join contexts, query relationship existence with joins, and sort by related columns/aggregations—all with cleaner, more readable queries.
join() calls with a consistent, maintainable pattern across the codebase, especially in legacy systems with verbose SQL.join('table', ...) with joinRelationship('relation').whereExists() logic, as behavior differs subtly (e.g., powerJoinHas vs has()).whereExists() for large datasets (avoids subqueries).select() or eager loading.select() clauses or use with() for related data.imageable_type, but single-morphable-type limitation may require workarounds for multi-type relationships.withGlobalScopes() in callbacks, risking forgotten scopes in production.deleted_at IS NULL; may surprise teams expecting withTrashed() behavior.posts.comments.votes) can generate verbose SQL, complicating debugging.->toSql()) during development.joinRelationship() vs join() for critical queries?whereExists()?hasManyThrough, polymorphic, many-to-many).join('posts as p on p.user_id = users.id')).User::join('posts') → User::joinRelationship('posts')).->toSql().posts.comments) and polymorphic relationships.joinRelationship('posts', fn ($join) => $join->published())).has()/whereHas() with powerJoinHas()/powerJoinWhereHas() for performance-critical paths.orderByPowerJoinsCount('posts.id')).join() calls in favor of joinRelationship().spatie/laravel-query-builder) may need testing.spatie/laravel-medialibrary, laravel-nestedset, or other relationship-heavy packages.composer require kirschbaum-development/eloquent-power-joins
^3.0).UserTest::testPostsJoin()).DatabaseMigrations or RefreshDatabase for join-heavy test suites.belongsToMany with conditions").where('posts.approved', true)) requires updating one place (the relationship definition or callback).['posts' => fn ($join) => ...]) can become hard to debug.joinRelationship() calls.infection or phpunit-mutation).config/database.php) for joined queries.try-catch for polymorphic/multi-table joins:
try {
User::joinRelationship('posts.comments')->get();
} catch (\Exception $e) {
Log::error('Join failed: ' . $e->getMessage(), ['sql' => $query->toSql()]);
}
select() is used to limit columns.withGlobalScopes() required).join() vs joinRelationship()."posts.user_id).select() to avoid SELECT *.posts.comments.votes may be slower than posts + comments separately).EXPLAIN ANALYZE for joined queries in production.How can I help you explore Laravel packages today?