From 142f81537b1ad2e2fb931e4528275ef0ff3a4d43 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Thu, 23 Sep 2021 14:02:28 +0100 Subject: [PATCH 01/14] Add failing test for whereBelongsTo --- .../Database/DatabaseEloquentBuilderTest.php | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 8e36ff1dc48e..d465b03992e9 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -4,6 +4,7 @@ use BadMethodCallException; use Closure; +use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Eloquent\Builder; @@ -906,6 +907,45 @@ public function testPostgresOperatorsWhere() $this->assertEquals($result, $builder); } + public function testWhereBelongsTo() + { + $db = new DB; + + $db->addConnection([ + 'driver' => 'sqlite', + 'database' => ':memory:', + ]); + + $db->bootEloquent(); + $db->setAsGlobal(); + + $schema = Model::getConnectionResolver() + ->connection() + ->getSchemaBuilder(); + + $schema->create('where_belongs_to_stubs', function ($table) { + $table->increments('id'); + $table->integer('parent_id'); + }); + + EloquentBuilderTestWhereBelongsToStub::query()->insert([ + ['id' => 1, 'parent_id' => 2], + ['id' => 2, 'parent_id' => 1], + ]); + + $related = EloquentBuilderTestWhereBelongsToStub::query()->find(1); + + $model = new EloquentBuilderTestWhereBelongsToStub; + + $query = $model->query()->whereBelongsTo($related); + $this->assertSame($query->toSql(), 'select * from "where_belongs_to_stubs" where "parent_id" = ?'); + + $query = $model->query()->whereBelongsTo($related, 'parent'); + $this->assertSame($query->toSql(), 'select * from "where_belongs_to_stubs" where "parent_id" = ?'); + + $schema->drop('where_belongs_to_stubs'); + } + public function testDeleteOverride() { $builder = $this->getBuilder(); @@ -1948,3 +1988,18 @@ class EloquentBuilderTestStubStringPrimaryKey extends Model protected $keyType = 'string'; } + +class EloquentBuilderTestWhereBelongsToStub extends Model +{ + protected $table = 'where_belongs_to_stubs'; + + public function eloquentBuilderTestWhereBelongsToStub() + { + return $this->belongsTo(self::class, 'parent_id', 'id', 'parent'); + } + + public function parent() + { + return $this->belongsTo(self::class, 'parent_id', 'id', 'parent'); + } +} From cbb3511ee0f967b85c39049fe94461d5563e84d7 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Thu, 23 Sep 2021 14:02:37 +0100 Subject: [PATCH 02/14] Implement whereBelongsTo --- src/Illuminate/Database/Eloquent/Builder.php | 35 ++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 15075432e492..eac76b27f9c1 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -8,6 +8,7 @@ use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Concerns\BuildsQueries; use Illuminate\Database\Concerns\ExplainsQueries; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -305,6 +306,40 @@ public function orWhere($column, $operator = null, $value = null) return $this->where($column, $operator, $value, 'or'); } + /** + * Add a "BelongsTo" relationship where clause to the query. + * + * @param \Illuminate\Database\Eloquent\Model $related + * @param string $relationship + * @param string $boolean + * @return $this + */ + public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') + { + if ($relationshipName === null) { + $relationshipName = Str::camel(class_basename(get_class($related))); + } + + if (! $this->model->isRelation($relationshipName)) { + return $this; + } + + $relationship = $this->model->{$relationshipName}(); + + if (! $relationship instanceof BelongsTo) { + return $this; + } + + $this->where( + $relationship->getForeignKeyName(), + '=', + $related->getAttributeValue($relationship->getOwnerKeyName()), + $boolean, + ); + + return $this; + } + /** * Add an "order by" clause for a timestamp to the query. * From fa1cbdb5a9681cba56a7cbe38b319b11026beb33 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Thu, 23 Sep 2021 15:35:46 +0100 Subject: [PATCH 03/14] mock in tests --- .../Database/DatabaseEloquentBuilderTest.php | 48 +++++++------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index d465b03992e9..0dd0c48ff883 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -4,7 +4,6 @@ use BadMethodCallException; use Closure; -use Illuminate\Database\Capsule\Manager as DB; use Illuminate\Database\ConnectionInterface; use Illuminate\Database\ConnectionResolverInterface; use Illuminate\Database\Eloquent\Builder; @@ -909,41 +908,23 @@ public function testPostgresOperatorsWhere() public function testWhereBelongsTo() { - $db = new DB; - - $db->addConnection([ - 'driver' => 'sqlite', - 'database' => ':memory:', + $related = new EloquentBuilderTestWhereBelongsToStub([ + 'id' => 1, + 'parent_id' => 2, ]); - $db->bootEloquent(); - $db->setAsGlobal(); - - $schema = Model::getConnectionResolver() - ->connection() - ->getSchemaBuilder(); - - $schema->create('where_belongs_to_stubs', function ($table) { - $table->increments('id'); - $table->integer('parent_id'); - }); - - EloquentBuilderTestWhereBelongsToStub::query()->insert([ - ['id' => 1, 'parent_id' => 2], - ['id' => 2, 'parent_id' => 1], + $parent = new EloquentBuilderTestWhereBelongsToStub([ + 'id' => 2, + 'parent_id' => 1, ]); - $related = EloquentBuilderTestWhereBelongsToStub::query()->find(1); - - $model = new EloquentBuilderTestWhereBelongsToStub; - - $query = $model->query()->whereBelongsTo($related); - $this->assertSame($query->toSql(), 'select * from "where_belongs_to_stubs" where "parent_id" = ?'); - - $query = $model->query()->whereBelongsTo($related, 'parent'); - $this->assertSame($query->toSql(), 'select * from "where_belongs_to_stubs" where "parent_id" = ?'); + $builder = $this->getBuilder(); + $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs'); + $builder->setModel($related); + $builder->getQuery()->shouldReceive('where')->once()->with('parent_id', '=', 2, 'and'); - $schema->drop('where_belongs_to_stubs'); + $result = $builder->whereBelongsTo($parent, 'parent'); + $this->assertEquals($result, $builder); } public function testDeleteOverride() @@ -1991,7 +1972,10 @@ class EloquentBuilderTestStubStringPrimaryKey extends Model class EloquentBuilderTestWhereBelongsToStub extends Model { - protected $table = 'where_belongs_to_stubs'; + protected $fillable = [ + 'id', + 'parent_id', + ]; public function eloquentBuilderTestWhereBelongsToStub() { From 6374f979224c79309067cd98ccfc72049cb88d0c Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Thu, 23 Sep 2021 15:39:13 +0100 Subject: [PATCH 04/14] Add test for relationship guess --- tests/Database/DatabaseEloquentBuilderTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 0dd0c48ff883..88934b56692f 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -923,6 +923,14 @@ public function testWhereBelongsTo() $builder->setModel($related); $builder->getQuery()->shouldReceive('where')->once()->with('parent_id', '=', 2, 'and'); + $result = $builder->whereBelongsTo($parent); + $this->assertEquals($result, $builder); + + $builder = $this->getBuilder(); + $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs'); + $builder->setModel($related); + $builder->getQuery()->shouldReceive('where')->once()->with('parent_id', '=', 2, 'and'); + $result = $builder->whereBelongsTo($parent, 'parent'); $this->assertEquals($result, $builder); } From 178f7bfbc211e1779a6ae8e308aab7d126ce4cf9 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Fri, 24 Sep 2021 19:25:02 +0100 Subject: [PATCH 05/14] Add exceptions --- src/Illuminate/Database/Eloquent/Builder.php | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index eac76b27f9c1..0c73c76ed6e2 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -309,10 +309,12 @@ public function orWhere($column, $operator = null, $value = null) /** * Add a "BelongsTo" relationship where clause to the query. * - * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship - * @param string $boolean + * @param \Illuminate\Database\Eloquent\Model $related + * @param string $relationship + * @param string $boolean * @return $this + * + * @throws \Exception */ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') { @@ -321,12 +323,16 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a } if (! $this->model->isRelation($relationshipName)) { + throw new Exception("Relationship [{$relationshipName}] does not exist on the Eloquent builder model."); + return $this; } $relationship = $this->model->{$relationshipName}(); if (! $relationship instanceof BelongsTo) { + throw new Exception("Relationship [{$relationshipName}] is not of type BelongsTo."); + return $this; } From 59e5f6667539ab9af9919a239ae57e72830f44d4 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Fri, 24 Sep 2021 19:25:28 +0100 Subject: [PATCH 06/14] Remove early returns --- src/Illuminate/Database/Eloquent/Builder.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 0c73c76ed6e2..58fa16f13cbb 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -324,16 +324,12 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a if (! $this->model->isRelation($relationshipName)) { throw new Exception("Relationship [{$relationshipName}] does not exist on the Eloquent builder model."); - - return $this; } $relationship = $this->model->{$relationshipName}(); if (! $relationship instanceof BelongsTo) { throw new Exception("Relationship [{$relationshipName}] is not of type BelongsTo."); - - return $this; } $this->where( From 2ef3433b28a41e99dea2f85d4484bb6fec6d76a1 Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Fri, 24 Sep 2021 19:26:37 +0100 Subject: [PATCH 07/14] Update Builder.php --- src/Illuminate/Database/Eloquent/Builder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 58fa16f13cbb..8efdc8d55069 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -309,9 +309,9 @@ public function orWhere($column, $operator = null, $value = null) /** * Add a "BelongsTo" relationship where clause to the query. * - * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship - * @param string $boolean + * @param \Illuminate\Database\Eloquent\Model $related + * @param string $relationship + * @param string $boolean * @return $this * * @throws \Exception From 4a4c1debce8b403be84da2ead84032377d3db87c Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Fri, 24 Sep 2021 19:27:09 +0100 Subject: [PATCH 08/14] Update Builder.php --- src/Illuminate/Database/Eloquent/Builder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 8efdc8d55069..cd82ac96b1f8 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -310,8 +310,8 @@ public function orWhere($column, $operator = null, $value = null) * Add a "BelongsTo" relationship where clause to the query. * * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship - * @param string $boolean + * @param string $relationship + * @param string $boolean * @return $this * * @throws \Exception From 9aa78b37f48cd7374d0ec0cea3e4a5982fc22fee Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Sat, 25 Sep 2021 07:43:20 +0100 Subject: [PATCH 09/14] Throw RelationNotFoundException --- src/Illuminate/Database/Eloquent/Builder.php | 8 ++++++-- .../Database/Eloquent/RelationNotFoundException.php | 9 +++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index cd82ac96b1f8..9aff9e4580da 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -323,13 +323,17 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a } if (! $this->model->isRelation($relationshipName)) { - throw new Exception("Relationship [{$relationshipName}] does not exist on the Eloquent builder model."); + $modelClass = get_class($this->model); + + throw RelationNotFoundException::make($modelClass, $relationshipName); } $relationship = $this->model->{$relationshipName}(); if (! $relationship instanceof BelongsTo) { - throw new Exception("Relationship [{$relationshipName}] is not of type BelongsTo."); + $modelClass = get_class($this->model); + + throw RelationNotFoundException::make($modelClass, $relationshipName, BelongsTo::class); } $this->where( diff --git a/src/Illuminate/Database/Eloquent/RelationNotFoundException.php b/src/Illuminate/Database/Eloquent/RelationNotFoundException.php index 5acc0b309562..6a2e44fd8b81 100755 --- a/src/Illuminate/Database/Eloquent/RelationNotFoundException.php +++ b/src/Illuminate/Database/Eloquent/RelationNotFoundException.php @@ -25,13 +25,18 @@ class RelationNotFoundException extends RuntimeException * * @param object $model * @param string $relation + * @param string $type * @return static */ - public static function make($model, $relation) + public static function make($model, $relation, $type = null) { $class = get_class($model); - $instance = new static("Call to undefined relationship [{$relation}] on model [{$class}]."); + $instance = new static( + $type === null ? + "Call to undefined relationship [{$relation}] on model [{$class}]." : + "Call to undefined relationship [{$relation}] on model [{$class}] of type [{$type}].", + ); $instance->model = $class; $instance->relation = $relation; From 629f5112dd36cbc38b92ce3c099e7cb964d729ca Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Sat, 25 Sep 2021 07:47:31 +0100 Subject: [PATCH 10/14] Refactor to catch BadMethodCallException --- src/Illuminate/Database/Eloquent/Builder.php | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 9aff9e4580da..2ae46517c519 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -322,18 +322,14 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a $relationshipName = Str::camel(class_basename(get_class($related))); } - if (! $this->model->isRelation($relationshipName)) { - $modelClass = get_class($this->model); - - throw RelationNotFoundException::make($modelClass, $relationshipName); + try { + $relationship = $this->model->{$relationshipName}(); + } catch (BadMethodCallException $exception) { + throw RelationNotFoundException::make($this->model, $relationshipName); } - $relationship = $this->model->{$relationshipName}(); - if (! $relationship instanceof BelongsTo) { - $modelClass = get_class($this->model); - - throw RelationNotFoundException::make($modelClass, $relationshipName, BelongsTo::class); + throw RelationNotFoundException::make($this->model, $relationshipName, BelongsTo::class); } $this->where( From 220ee8a35f37c3385c6c5ecf290cbfc5df90c6db Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Mon, 27 Sep 2021 19:45:27 +0100 Subject: [PATCH 11/14] Remove rogue get_class --- src/Illuminate/Database/Eloquent/Builder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 2ae46517c519..db5f16b3b771 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -319,7 +319,7 @@ public function orWhere($column, $operator = null, $value = null) public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') { if ($relationshipName === null) { - $relationshipName = Str::camel(class_basename(get_class($related))); + $relationshipName = Str::camel(class_basename($related)); } try { From ad34f338fc29d1762351199d32390eebf2d277ea Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Mon, 27 Sep 2021 20:13:33 +0100 Subject: [PATCH 12/14] move method to trait --- src/Illuminate/Database/Eloquent/Builder.php | 37 ------------------ .../Concerns/QueriesRelationships.php | 39 +++++++++++++++++++ 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index db5f16b3b771..15075432e492 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -8,7 +8,6 @@ use Illuminate\Contracts\Support\Arrayable; use Illuminate\Database\Concerns\BuildsQueries; use Illuminate\Database\Concerns\ExplainsQueries; -use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -306,42 +305,6 @@ public function orWhere($column, $operator = null, $value = null) return $this->where($column, $operator, $value, 'or'); } - /** - * Add a "BelongsTo" relationship where clause to the query. - * - * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship - * @param string $boolean - * @return $this - * - * @throws \Exception - */ - public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') - { - 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->where( - $relationship->getForeignKeyName(), - '=', - $related->getAttributeValue($relationship->getOwnerKeyName()), - $boolean, - ); - - return $this; - } - /** * Add an "order by" clause for a timestamp to the query. * diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php index c2baa667bc2a..94beb718ae05 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php @@ -2,8 +2,11 @@ namespace Illuminate\Database\Eloquent\Concerns; +use BadMethodCallException; use Closure; use Illuminate\Database\Eloquent\Builder; +use Illuminate\Database\Eloquent\RelationNotFoundException; +use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\Relations\Relation; use Illuminate\Database\Query\Builder as QueryBuilder; @@ -618,6 +621,42 @@ public function withExists($relation) return $this->withAggregate($relation, '*', 'exists'); } + /** + * Add a "BelongsTo" relationship where clause to the query. + * + * @param \Illuminate\Database\Eloquent\Model $related + * @param string $relationship + * @param string $boolean + * @return $this + * + * @throws \Exception + */ + public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') + { + 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->where( + $relationship->getForeignKeyName(), + '=', + $related->getAttributeValue($relationship->getOwnerKeyName()), + $boolean, + ); + + return $this; + } + /** * Add the "has" condition where clause to the query. * From 9a9e2e36913a97b78721eaa016ca211ccbdf27fd Mon Sep 17 00:00:00 2001 From: Dan Harrin Date: Mon, 27 Sep 2021 20:20:08 +0100 Subject: [PATCH 13/14] qualify foreign key --- .../Database/Eloquent/Concerns/QueriesRelationships.php | 2 +- tests/Database/DatabaseEloquentBuilderTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php index 94beb718ae05..ae5dd6e30951 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php @@ -648,7 +648,7 @@ public function whereBelongsTo($related, $relationshipName = null, $boolean = 'a } $this->where( - $relationship->getForeignKeyName(), + $relationship->getQualifiedForeignKeyName(), '=', $related->getAttributeValue($relationship->getOwnerKeyName()), $boolean, diff --git a/tests/Database/DatabaseEloquentBuilderTest.php b/tests/Database/DatabaseEloquentBuilderTest.php index 88934b56692f..863344c4ec46 100755 --- a/tests/Database/DatabaseEloquentBuilderTest.php +++ b/tests/Database/DatabaseEloquentBuilderTest.php @@ -921,7 +921,7 @@ public function testWhereBelongsTo() $builder = $this->getBuilder(); $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs'); $builder->setModel($related); - $builder->getQuery()->shouldReceive('where')->once()->with('parent_id', '=', 2, 'and'); + $builder->getQuery()->shouldReceive('where')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', '=', 2, 'and'); $result = $builder->whereBelongsTo($parent); $this->assertEquals($result, $builder); @@ -929,7 +929,7 @@ public function testWhereBelongsTo() $builder = $this->getBuilder(); $builder->shouldReceive('from')->with('eloquent_builder_test_where_belongs_to_stubs'); $builder->setModel($related); - $builder->getQuery()->shouldReceive('where')->once()->with('parent_id', '=', 2, 'and'); + $builder->getQuery()->shouldReceive('where')->once()->with('eloquent_builder_test_where_belongs_to_stubs.parent_id', '=', 2, 'and'); $result = $builder->whereBelongsTo($parent, 'parent'); $this->assertEquals($result, $builder); From 19d341f1dbefbef4ef272402f10027516efa4bdf Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Tue, 28 Sep 2021 14:27:08 -0500 Subject: [PATCH 14/14] formatting --- .../Concerns/QueriesRelationships.php | 86 +++++++++++-------- .../Eloquent/RelationNotFoundException.php | 8 +- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php index ae5dd6e30951..aae3ffb11860 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php +++ b/src/Illuminate/Database/Eloquent/Concerns/QueriesRelationships.php @@ -458,6 +458,56 @@ public function orWhereMorphedTo($relation, $model) return $this->whereMorphedTo($relation, $model, 'or'); } + /** + * Add a "belongs to" relationship where clause to the query. + * + * @param \Illuminate\Database\Eloquent\Model $related + * @param string $relationship + * @param string $boolean + * @return $this + * + * @throws \Exception + */ + public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') + { + 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->where( + $relationship->getQualifiedForeignKeyName(), + '=', + $related->getAttributeValue($relationship->getOwnerKeyName()), + $boolean, + ); + + return $this; + } + + /** + * Add an "BelongsTo" relationship with an "or where" clause to the query. + * + * @param \Illuminate\Database\Eloquent\Model $related + * @param string $relationship + * @return $this + * + * @throws \Exception + */ + public function orWhereBelongsTo($related, $relationshipName = null) + { + return $this->whereBelongsTo($related, $relationshipName, 'or'); + } + /** * Add subselect queries to include an aggregate value for a relationship. * @@ -621,42 +671,6 @@ public function withExists($relation) return $this->withAggregate($relation, '*', 'exists'); } - /** - * Add a "BelongsTo" relationship where clause to the query. - * - * @param \Illuminate\Database\Eloquent\Model $related - * @param string $relationship - * @param string $boolean - * @return $this - * - * @throws \Exception - */ - public function whereBelongsTo($related, $relationshipName = null, $boolean = 'and') - { - 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->where( - $relationship->getQualifiedForeignKeyName(), - '=', - $related->getAttributeValue($relationship->getOwnerKeyName()), - $boolean, - ); - - return $this; - } - /** * Add the "has" condition where clause to the query. * diff --git a/src/Illuminate/Database/Eloquent/RelationNotFoundException.php b/src/Illuminate/Database/Eloquent/RelationNotFoundException.php index 6a2e44fd8b81..73257bb101e0 100755 --- a/src/Illuminate/Database/Eloquent/RelationNotFoundException.php +++ b/src/Illuminate/Database/Eloquent/RelationNotFoundException.php @@ -25,7 +25,7 @@ class RelationNotFoundException extends RuntimeException * * @param object $model * @param string $relation - * @param string $type + * @param string|null $type * @return static */ public static function make($model, $relation, $type = null) @@ -33,9 +33,9 @@ public static function make($model, $relation, $type = null) $class = get_class($model); $instance = new static( - $type === null ? - "Call to undefined relationship [{$relation}] on model [{$class}]." : - "Call to undefined relationship [{$relation}] on model [{$class}] of type [{$type}].", + is_null($type) + ? "Call to undefined relationship [{$relation}] on model [{$class}]." + : "Call to undefined relationship [{$relation}] on model [{$class}] of type [{$type}].", ); $instance->model = $class;