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.
hasMany, belongsToMany). This reduces friction for teams already familiar with Laravel’s ecosystem.deleted_at checks).powerJoinHas as an alternative to whereExists for better performance in some cases (e.g., when joining is more efficient than subqueries).join() calls with joinRelationship(), reducing cognitive load and risk of SQL injection (since relationships are defined in models).// Existing code
User::join('posts', 'posts.user_id', '=', 'users.id')->get();
// With package
User::joinRelationship('posts')->get();
posts.comments.users) may generate overly complex SQL, leading to:
toSql() to inspect generated queries and optimize with explicit select() clauses.published()) are applied within join contexts, but not all Eloquent query methods are supported (e.g., orderBy with relationships). This may require workarounds.
orderBy on a joined table might fail unless explicitly handled.withGlobalScopes()) can introduce unexpected behavior if scopes modify the query in ways incompatible with joins (e.g., adding where clauses that conflict with join conditions).powerJoinHas vs. has results differ).powerJoinHas vs. whereExists for our most critical queries? (Joins may be faster for large datasets but slower for small ones.)created_at in both parent and joined tables)? If so, explicit select() clauses will be necessary.join() calls? Will migration require significant refactoring?laravel/scout (for search-as-you-type with joined data).spatie/laravel-permission (for role-based joins).laravel/nova (if using Nova’s query builder).assertDatabaseHas can be extended to verify joined data).join() calls with joinRelationship() to validate output parity.// Before
User::join('posts', 'posts.user_id', '=', 'users.id')
->join('comments', 'comments.post_id', '=', 'posts.id')
->where('posts.published', true)
->get();
// After
User::joinRelationship('posts.comments', [
'posts' => fn ($join) => $join->where('published', true),
])->get();
hasMany(Post::class)->published()) to leverage the package’s automatic condition application.toSql() to compare old vs. new query plans.select() clauses to avoid SELECT * conflicts.join() calls in favor of joinRelationship().with), but joins are executed immediately (not deferred like with).cursor(), chunk(), and other query methods.stancl/tenancy, spatie/laravel-medialibrary). Test with:
User::joinRelationship('posts')->withTenancy()->get(); // If using tenancy
joinRelationship() to Eloquent’s query builder. Ensure no naming conflicts with existing macros.composer.json and run composer update.3.*.public function test_join_relationship()
{
$user = User::joinRelationship('posts')->first();
$this->assertDatabaseHas('posts', ['user_id' => $user->id]);
}
powerJoinHas vs. has).join() calls from codebase over time, reducing technical debt.select() clauses.orderBy in joins).leftJoinRelationship() or limit joined columns.How can I help you explore Laravel packages today?