diff --git a/README.md b/README.md index 0517afe..f548a0e 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,13 @@ User::query()->joinRelation('posts as articles.comments as threads', [ }); ``` +The join type can also be mixed: +```php +User::query()->joinRelation('posts.comments', [ + 'comments' => function ($join) { $join->type = 'left'; } +}); +``` + #### Through-Syntax diff --git a/src/Mixins/JoinsRelationships.php b/src/Mixins/JoinsRelationships.php index fcc76b3..f1e2c34 100644 --- a/src/Mixins/JoinsRelationships.php +++ b/src/Mixins/JoinsRelationships.php @@ -91,8 +91,10 @@ public function joinRelation() $this->applyJoinScopes($joinQuery); } + $joinType = $joinQuery->getJoinType(); + $this->addJoinRelationWhere( - $joinQuery, $relation, $type + $joinQuery, $relation, $joinType ?: $type ); return ! is_null($relatedQuery) ? $joinQuery : $this; @@ -232,6 +234,31 @@ protected function callJoinScope() }; } + /** + * Defines the mixin for {@see $query->getJoinType()}. + * + * @return \Closure + */ + protected function getJoinType() + { + /** + * Returns the custom provided join type. + * + * @return string|null + */ + return function () { + if (! property_exists($this, 'type')) { + return null; + } + + try { + $type = $this->type; + } finally { + return $type; + } + }; + } + /** * Defines the mixin for {@see $query->addJoinRelationWhere()}. * diff --git a/tests/Unit/JoinsRelationshipsTest.php b/tests/Unit/JoinsRelationshipsTest.php index 6eff81e..53ea732 100644 --- a/tests/Unit/JoinsRelationshipsTest.php +++ b/tests/Unit/JoinsRelationshipsTest.php @@ -194,4 +194,20 @@ public function multiconstraint_skip_middle_associative(Closure $query, string $ $this->assertEquals([true, 'thumbs-up'], $builder->getBindings()); $this->assertEquals($builderClass, get_class($builder)); } + + /** + * @test + * @dataProvider queryDataProvider + */ + public function multiconstraint_mix_type(Closure $query, string $builderClass) + { + $builder = $query(new EloquentUserModelStub) + ->joinRelation('posts.comments.likes', [ + 'posts' => function ($join) { $join->type = 'left'; }, + 'likes' => function ($join) { $join->type = 'right'; } + ]); + + $this->assertEquals('select * from "users" left join "posts" on "posts"."user_id" = "users"."id" inner join "comments" on "comments"."post_id" = "posts"."id" right join "likes" on "likes"."comment_id" = "comments"."id"', $builder->toSql()); + $this->assertEquals($builderClass, get_class($builder)); + } }