Blog Detail

22

Apr
Add the Ability to Join on a Relationship by Name in Laravel cover image

arrow_back Add the Ability to Join on a Relationship by Name in Laravel

Laravel Relation Joins is a package that makes joining a breeze by leveraging the relationships you have already defined. Eloquent doesn’t offer any tools for joining, so we’ve been stuck with the base query builder joins. While Eloquent does have the “has” concept for existence, there are still times when you want to return information about the related entities, or aggregate information together.

Aside from relationships themselves, Eloquent’s omission of relationship joins means that you can’t leverage several powerful features of Eloquent, such as model scopes and soft deletes. This package aims to correct all of that.

Installation

You can install this package using Composer:

composer require reedware/laravel-relation-joins

This package leverages auto-discovery for its service provider. If you have auto discovery disabled for this package, you’ll need to manually register the service provider:

Reedware\LaravelRelationJoins\LaravelRelationJoinServiceProvider::class

Usage

1. Performing a join via relationship

This is the entire point of this package, so here’s a basic example:

User::query()->joinRelation('posts');

This will apply a join from the User model through the posts relation, leveraging any query scopes (such as soft deletes) automatically.

You can perform joins over all relationship types, including polymorphic relationships. Additionally, you can perform the other types of joins, using a syntax similar to the base query builder:

User::query()->leftJoinRelation('posts');
User::query()->rightJoinRelation('posts');
User::query()->crossJoinRelation('posts');

2. Joining to nested relationships

One of the shining abilities to be able to join through relationships shows up when you have to navigate through a nested web of relationships. When trying to join on a relation through another relation, you can use the “dot” syntax, similar to how the “has” and “with” concepts work:

User::query()->joinRelation('posts.comments');

3. Adding join constraints

This is honestly where I felt a lot of the existing solutions were lacking. They either created custom “where” clauses, or limited the query to only supporting certain types of “where” clauses. With this package, there are no known restrictions, and the means of adding the constraints is very intuitive:

User::query()->joinRelation('posts', function ($join) {
    $join->where('posts.created_at', '>=', '2019-01-01');
});

This will tack on the specific constraints to the already provided relationship constraints, making this really easy to use.

4. Joining on circular relationships

This package also supports joining on circular relations, and handles it the same way the “has” concept does:

public function employees()
{
    return $this->hasMany(static::class, 'manager_id', 'id');
}

User::query()->joinRelation('employees');

// SQL: select * from "users" inner join "users" as "laravel_reserved_0" on "laravel_reserved_0"."manager_id" = "users"."id"

Now clearly, if you’re wanting to apply constraints on the employees relation, having this sort of naming convention isn’t desirable. This brings me to the next feature:

5. Anonymous Joins

In rare circumstances, you may find yourself in a situation where you don’t want to define a relationship on a model, but you still want to join on it as if it existed. You can do this by passing in the relationship itself:

$relation = Relation::noConstraints(function () {
    return (new User)
        ->belongsTo(Country::class, 'country_name', 'name');
});

User::query()->joinRelation($relation);
// SQL: select * from "users" inner join "countries" on "countries"."name" = "users"."country_name"

This package has a lot more features and options with code examples. If you want to dig more you can visit its complete documentation and source code on Github.

Published at : 22-04-2022

Author : Rizwan Aslam
AUTHOR
Rizwan Aslam

I am a highly results-driven professional with 12+ years of collective experience in the grounds of web application development especially in laravel, native android application development in java, and desktop application development in the dot net framework. Now managing a team of expert developers at Codebrisk.

Launch your project

Launch project