Open-source project
kirschbaum-development/eloquent-power-joins avatar
kirschbaum-development/eloquent-power-joins

eloquent-power-joins: relationship joins for Laravel

The Laravel magic you know, now applied to joins.

1,570 stars102 forksPHPMIT

At a glance

What is it?
eloquent-power-joins adds relationship-aware joins, existence checks, related-column sorting, and aggregate sorting to Laravel Eloquent. It reduces repeated join wiring while retaining support for polymorphic relationships, soft deletes, scopes, aliases, and nested conditions.
Who is it for?
Adopt eloquent-power-joins when your Laravel application already defines relationships that are being rewritten as manual joins, especially for nested, polymorphic, or conditionally constrained queries. Do not adopt it merely to avoid learning SQL joins, because relationship-aware queries still produce joins and can change query semantics.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 14 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • kirschbaum-development/eloquent-power-joins1,570 ★ · -2
Star history
Repository2026-10-172026-11-07
kirschbaum-development/eloquent-power-joins1.6k1.6k

-2 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Why relationship joins matter in eloquent-power-joins

Laravel developers often express related records through Eloquent relationships, then have to reproduce those relationships in raw query-builder joins. That creates two descriptions of the same association: one in PHP for model navigation and another in SQL for a particular query. eloquent-power-joins is intended to reduce that duplication. It is for Laravel applications that need relational filtering or ordering, but want the query builder to use relationship declarations instead of repeating table names and foreign-key paths.

The clearest transformation is a multi-table user, post, and comment join. Instead of joining `posts` to `users`, then joining `comments` to `posts`, the package accepts the existing `posts.comments` relationship path. The relationship metadata becomes part of the SQL construction. That matters most when relationships already contain logic such as polymorphic type constraints, soft-delete rules, aliases, scopes, or additional conditions.

This package does not replace ordinary Eloquent relationships. Its scope is narrower: relationship declarations can also drive joins and certain ordering operations. The README does not document a general replacement for Eloquent's `with`, eager loading, or relationship existence methods. It specifically presents `powerJoinHas()` as a way to use joins instead of a `where exists` style query.

The query builder flow exposed by Eloquent

Based on the public API shown in the README, the package extends Eloquent query building with relationship path names. `User::joinRelationship('posts.comments')` receives a dot-separated relationship path and derives the joins required to reach both related tables. The application supplies relationship names rather than repeating each `join()` call, selected table, and equality condition.

Relationship metadata can affect more than the base join path. The documentation states that polymorphic relationships, soft deletes, model scopes, aliases, and extra relationship conditions are handled. In practical terms, that means a query author should inspect the resulting SQL when those features participate. A relationship method is not merely a name in this package's model, since constraints defined at the relationship level can influence the SQL.

The API also covers three adjacent operations. `powerJoinHas()` expresses relationship existence through joins rather than `where exists`. `orderByPowerJoins()` orders by a related column such as `profile.city`. `orderByPowerJoinsCount()` orders by an aggregation from a related table, such as counting `comments.id` in descending order. These operations extend the package beyond table retrieval: it can participate in both filtering and result ordering.

Composer installation and the first User join

The README gives one installation command. It requires the package through Composer and therefore adds it to a PHP project that already uses Laravel and Eloquent.

bash
composer require kirschbaum-development/eloquent-power-joins

After installation, the first useful query requires models with an existing `posts` relationship on `User` and a `comments` relationship on `Post`. Replace the class and relationship names if the application defines them differently.

php
User::joinRelationship('posts.comments');

This is the manual query stated in the README:

php
User::select('users.*')
    ->join('posts', 'posts.user_id', '=', 'users.id')
    ->join('comments', 'comments.post_id', '=', 'posts.id');

The relationship-based version removes explicit table and foreign-key wiring from this example. It does not, however, show SQL logging, result inspection, or a sample returned record. The README also does not state whether selecting `users.*` is necessary in every case, so an application should check its own selected columns and generated SQL instead of assuming identical hydration behavior.

Existence checks and related-table ordering

The documented API supports queries that are awkward to express cleanly when every related table must be wired by hand. `powerJoinHas()` is the clearest example:

php
User::powerJoinHas('posts');

The README identifies this as relationship existence through joins instead of `where exists`. That is an explicit query-strategy choice, not merely a shorter spelling of the same implementation. Applications that depend on SQL planner behavior or expect correlated subqueries should review the generated query before replacing an existing existence check.

Ordering follows the same relationship-driven model:

php
User::orderByPowerJoins('profile.city');

This directs Eloquent to order users using a column from the related `profile` path. The example indicates an order of relationship name plus column name, not the table qualification shown in the argument.

For aggregate ordering, the package exposes a separate method:

php
Post::orderByPowerJoinsCount('comments.id', 'desc');

The method name and example specify ordering by a count from the related `comments` table in descending order. The README does not document aggregation functions beyond this count form, null ordering, tie-breaking, or pagination behavior. Those details need verification against the package documentation and generated SQL for the Laravel version in use.

Eloquent convenience with relational constraints

The feature that distinguishes eloquent-power-joins from a small helper that concatenates relationship names is its handling of relationship constraints. According to the README, polymorphic relationships, soft deletes, model scopes, aliases, and extra conditions are considered when building the joins.

A direct SQL join does not automatically understand these Eloquent definitions. A polymorphic relationship, for example, carries more context than the columns used to identify a joined row. A soft-delete scope can also affect which related records qualify. Since eloquent-power-joins starts from declared relationships, it has access to this model-level context. The README does not expose the internal resolver classes or the exact order in which conditions are combined, so the safe assessment is based on its documented support rather than an implementation claim.

Aliases deserve particular attention. The package says it handles aliased relationships, but the README supplies no example showing the alias syntax or resulting SQL. If a query uses aliases, inspect the actual generated statements before assuming that the selected root columns retain the same aliases as a handwritten join. Scopes and extra conditions are also worth checking in bulk queries, where developers may not normally inspect SQL generated by a convenience method.

Where eloquent-power-joins is the wrong query tool

The package is a poor fit when the join is not represented by an Eloquent relationship. Database views, reporting queries, database-specific optimizer hints, or joins assembled outside the model layer may have no relationship path for the package to resolve. In those cases, Laravel's ordinary query builder remains the direct interface.

It is also a questionable replacement for eager loading. The README presents `joinRelationship()`, existence checking, and related ordering, but it does not claim that `joinRelationship()` loads nested models into their normal Eloquent relationship properties. A join returns a flattened SQL result; eager loading is a different data-fetching mechanism. Developers should not adopt this package as a way to avoid separate relationship queries unless they specifically want join-based results and have checked column selection.

Another constraint is observability. Relationship path strings can fail because the named relation is missing or differs from the application method. The README does not document error messages or fallback behavior for invalid paths. It also does not state that generated joins can be previewed through a documented debugging method. Query logging and direct SQL inspection may therefore matter during integration, especially with scopes, polymorphic relations, and aliases.

Compared with writing SQL joins by hand, the package reduces repeated relationship wiring but moves behavior behind relationship interpretation. Compared with `where exists`, `powerJoinHas()` explicitly chooses joins. The right choice depends on whether the application values Eloquent relationship reuse enough to accept that dependency.

Release cadence, Laravel compatibility, and MIT licensing

The repository is not archived, and its last push was on 2026-10-14. The documented release history also lists version 4.3.5 on 2026-10-14, version 4.3.4 on 2026-09-25, and version 4.3.3 on 2026-07-23. This supports a recent maintenance signal based solely on the repository activity and release facts. It does not establish compatibility with every Laravel or PHP release.

The README badge states support for Laravel 11.x, 12.x, and 13.x. It does not give minimum PHP versions or Composer constraints in the README. `composer.json` exists in the repository, so package-level dependency requirements are available there, but their exact values cannot be confirmed from the README excerpt. Check that file against the application's PHP and Laravel versions before installation.

Upgrades require reviewing `CHANGELOG.md`, which the README names as the source for release changes. The repository also provides `composer test` as its test command:

bash
composer test

That command is for contributors or maintainers running the package's own test suite after a version change, not a documented end-user application check.

The project uses the MIT License. Its repository includes `LICENSE.md`. MIT licensing permits broad use and modification under the license's stated conditions, but this review does not interpret whether a particular deployment complies with obligations. Preserve the required license notice and review the actual `LICENSE.md` for the exact terms.

Editorial conclusion

Adopt eloquent-power-joins when your Laravel application already defines relationships that are being rewritten as manual joins, especially for nested, polymorphic, or conditionally constrained queries. Do not adopt it merely to avoid learning SQL joins, because relationship-aware queries still produce joins and can change query semantics. Verify first that your Laravel and PHP versions are supported, then compare its generated SQL with the joins currently used by the application.

Frequently asked questions

How do I install eloquent-power-joins in a Laravel application?

Install it through Composer with `composer require kirschbaum-development/eloquent-power-joins`. The README identifies Laravel 11.x, 12.x, and 13.x as supported versions.

How do I use an existing Eloquent relationship as a join?

Pass the relationship path to `joinRelationship()`, such as `User::joinRelationship('posts.comments')`. The package derives the joins from the declared relationships instead of requiring each table and foreign-key pair in the query.

Does eloquent-power-joins handle polymorphic relationships and soft deletes?

According to the README, the package handles polymorphic relationships and soft deletes, along with model scopes, aliases, and extra relationship conditions.

Can eloquent-power-joins sort results by a related column or aggregate?

Yes. The documented API includes `orderByPowerJoins('profile.city')` for a related column and `orderByPowerJoinsCount('comments.id', 'desc')` for an aggregate from a related table.

Official sources

  1. kirschbaum-development/eloquent-power-joins on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kirschbaum-development-eloquent-power-joins.svg)](https://hysenlabs.com/projects/kirschbaum-development-eloquent-power-joins)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/kirschbaum-development-eloquent-power-joins.svg)](https://hysenlabs.com/projects/kirschbaum-development-eloquent-power-joins)

Was this useful?