diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php index b310c5304f11..63cb031f970f 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php @@ -348,6 +348,72 @@ public function orWhereDoesntHaveMorph($relation, $types, Closure $callback = nu return $this->doesntHaveMorph($relation, $types, 'or', $callback); } + /** + * Add a basic where clause to a relationship query. + * + * @param string $relation + * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function whereRelation($relation, $column, $operator = null, $value = null) + { + return $this->whereHas($relation, function ($query) use ($column, $operator, $value) { + $query->where($column, $operator, $value); + }); + } + + /** + * Add an "or where" clause to a relationship query. + * + * @param string $relation + * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function orWhereRelation($relation, $column, $operator = null, $value = null) + { + return $this->orWhereHas($relation, function ($query) use ($column, $operator, $value) { + $query->where($column, $operator, $value); + }); + } + + /** + * Add a polymorphic relationship condition to the query with a where clause. + * + * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation + * @param string|array $types + * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function whereMorphRelation($relation, $types, $column, $operator = null, $value = null) + { + return $this->whereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) { + $query->where($column, $operator, $value); + }); + } + + /** + * Add a polymorphic relationship condition to the query with an "or where" clause. + * + * @param \Illuminate\Database\Eloquent\Relations\MorphTo|string $relation + * @param string|array $types + * @param \Closure|string|array|\Illuminate\Database\Query\Expression $column + * @param mixed $operator + * @param mixed $value + * @return \Illuminate\Database\Eloquent\Builder|static + */ + public function orWhereMorphRelation($relation, $types, $column, $operator = null, $value = null) + { + return $this->orWhereHasMorph($relation, $types, function ($query) use ($column, $operator, $value) { + $query->where($column, $operator, $value); + }); + } + /** * Add subselect queries to include an aggregate value for a relationship. * diff --git a/tests/Integration/Database/EloquentWhereHasTest.php b/tests/Integration/Database/EloquentWhereHasTest.php index 071c57a7d2b7..c46bfa44ce9d 100644 --- a/tests/Integration/Database/EloquentWhereHasTest.php +++ b/tests/Integration/Database/EloquentWhereHasTest.php @@ -41,6 +41,36 @@ protected function setUp(): void (new Comment)->commentable()->associate($post)->save(); } + public function testWhereRelation() + { + $users = User::whereRelation('posts', 'public', true)->get(); + + $this->assertEquals([1], $users->pluck('id')->all()); + } + + public function testOrWhereRelation() + { + $users = User::whereRelation('posts', 'public', true)->orWhereRelation('posts', 'public', false)->get(); + + $this->assertEquals([1, 2], $users->pluck('id')->all()); + } + + public function testWhereMorphRelation() + { + $comments = Comment::whereMorphRelation('commentable', '*', 'public', true)->get(); + + $this->assertEquals([1], $comments->pluck('id')->all()); + } + + public function testOrWhereMorphRelation() + { + $comments = Comment::whereMorphRelation('commentable', '*', 'public', true) + ->orWhereMorphRelation('commentable', '*', 'public', false) + ->get(); + + $this->assertEquals([1, 2], $comments->pluck('id')->all()); + } + public function testWithCount() { $users = User::whereHas('posts', function ($query) {