Skip to content

Commit

Permalink
Add whereBelongsToOneOf clause
Browse files Browse the repository at this point in the history
  • Loading branch information
erikgaal committed Mar 29, 2022
1 parent dc81d74 commit 605ec9e
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
53 changes: 53 additions & 0 deletions src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,59 @@ public function orWhereBelongsTo($related, $relationshipName = null)
return $this->whereBelongsTo($related, $relationshipName, 'or');
}

/**
* Add a "belongs to one of" relationship where clause to the query.
*
* @param \Illuminate\Database\Eloquent\Collection<\Illuminate\Database\Eloquent\Model> $values
* @param string|null $relationshipName
* @param string $boolean
* @return $this
*
* @throws \Illuminate\Database\Eloquent\RelationNotFoundException
*/
public function whereBelongsToOneOf($values, $relationshipName = null, $boolean = 'and')
{
if (! $related = $values->first()) {
return $this->whereNull($this->getModel()->getKeyName(), $boolean);
}

if ($relationshipName === null) {
$relationshipName = Str::camel(class_basename($related));
}

try {
$relationship = $this->model->{$relationshipName}();
} catch (BadMethodCallException $exception) {
throw RelationNotFoundException::make($this->model, $relationshipName);
}

if (! $relationship instanceof BelongsTo) {
throw RelationNotFoundException::make($this->model, $relationshipName, BelongsTo::class);
}

$this->whereIn(
$relationship->getQualifiedForeignKeyName(),
$values->pluck($relationship->getOwnerKeyName())->toArray(),
$boolean,
);

return $this;
}

/**
* Add a "belongs to one of" relationship with an or where clause to the query.
*
* @param \Illuminate\Database\Eloquent\Collection<\Illuminate\Database\Eloquent\Model> $values
* @param string|null $relationshipName
* @return $this
*
* @throws \Illuminate\Database\Eloquent\RelationNotFoundException
*/
public function orWhereBelongsToOneOf($values, string $relationshipName = null)
{
return $this->whereBelongsToOneOf($values, $relationshipName, 'or');
}

/**
* Add subselect queries to include an aggregate value for a relationship.
*
Expand Down
32 changes: 32 additions & 0 deletions tests/Database/DatabaseEloquentBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1055,6 +1055,38 @@ public function testWhereBelongsTo()
$this->assertEquals($result, $builder);
}

public function testWhereBelongsToOneOf()
{
$related = new EloquentBuilderTestWhereBelongsToStub([
'id' => 1,
'parent_id' => 2,
]);

$parents = new Collection([new EloquentBuilderTestWhereBelongsToStub([
'id' => 2,
'parent_id' => 1,
]), new EloquentBuilderTestWhereBelongsToStub([
'id' => 3,
'parent_id' => 1,
])]);

$builder = $this->getBuilder();
$builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs');
$builder->setModel($related);
$builder->getQuery()->shouldReceive('whereIn')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', [2, 3], 'and');

$result = $builder->whereBelongsToOneOf($parents);
$this->assertEquals($result, $builder);

$builder = $this->getBuilder();
$builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs');
$builder->setModel($related);
$builder->getQuery()->shouldReceive('whereIn')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', [2, 3], 'and');

$result = $builder->whereBelongsToOneOf($parents, 'parent');
$this->assertEquals($result, $builder);
}

public function testDeleteOverride()
{
$builder = $this->getBuilder();
Expand Down

0 comments on commit 605ec9e

Please sign in to comment.