Skip to content

Commit

Permalink
[11.x] Allow to remove scopes from BelongsToMany relation (#50945) (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
plumthedev authored Apr 9, 2024
1 parent f36f194 commit 24f16ba
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1563,7 +1563,7 @@ public function getPivotColumns()
*/
public function qualifyPivotColumn($column)
{
if ($this->getGrammar()->isExpression($column)) {
if ($this->query->getQuery()->getGrammar()->isExpression($column)) {
return $column;
}

Expand Down
26 changes: 26 additions & 0 deletions tests/Database/DatabaseEloquentBelongsToManyExpressionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Illuminate\Tests\Database;

use Exception;
use Illuminate\Database\Capsule\Manager as DB;
use Illuminate\Database\Eloquent\Model as Eloquent;
use Illuminate\Database\Eloquent\Relations\MorphToMany;
Expand Down Expand Up @@ -52,6 +53,31 @@ public function testQualifiedColumnExpression(): void
$this->assertEquals(3, $tags->first()->getKey());
}

public function testGlobalScopesAreAppliedToBelongsToManyRelation(): void
{
$this->seedData();
$post = DatabaseEloquentBelongsToManyExpressionTestTestPost::query()->firstOrFail();
DatabaseEloquentBelongsToManyExpressionTestTestTag::addGlobalScope(
'default',
static fn () => throw new Exception('Default global scope.')
);

$this->expectExceptionMessage('Default global scope.');
$post->tags()->get();
}

public function testGlobalScopesCanBeRemovedFromBelongsToManyRelation(): void
{
$this->seedData();
$post = DatabaseEloquentBelongsToManyExpressionTestTestPost::query()->firstOrFail();
DatabaseEloquentBelongsToManyExpressionTestTestTag::addGlobalScope(
'default',
static fn () => throw new Exception('Default global scope.')
);

$this->assertNotEmpty($post->tags()->withoutGlobalScopes()->get());
}

/**
* Setup the database schema.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Illuminate\Database\Query\Grammars\Grammar;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use stdClass;

class DatabaseEloquentBelongsToManyWithCastedAttributesTest extends TestCase
{
Expand Down Expand Up @@ -64,8 +65,8 @@ protected function getRelation()
$builder->shouldReceive('getModel')->andReturn($related);
$related->shouldReceive('qualifyColumn');
$builder->shouldReceive('join', 'where');
$builder->shouldReceive('getGrammar')->andReturn(
m::mock(Grammar::class, ['isExpression' => false])
$builder->shouldReceive('getQuery')->andReturn(
m::mock(stdClass::class, ['getGrammar' => m::mock(Grammar::class, ['isExpression' => false])])
);

return new BelongsToMany(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ public function testWithPivotValueMethodSetsDefaultArgumentsForInsertion()
$query = m::mock(stdClass::class);
$query->shouldReceive('from')->once()->with('club_user')->andReturn($query);
$query->shouldReceive('insert')->once()->with([['club_id' => 1, 'user_id' => 1, 'is_admin' => 1]])->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);

$relation->attach(1);
}
Expand All @@ -56,7 +55,9 @@ public function getRelationArguments()
$builder->shouldReceive('join')->once()->with('club_user', 'users.id', '=', 'club_user.user_id');
$builder->shouldReceive('where')->once()->with('club_user.club_id', '=', 1);
$builder->shouldReceive('where')->once()->with('club_user.is_admin', '=', 1, 'and');
$builder->shouldReceive('getGrammar')->andReturn(m::mock(Grammar::class, ['isExpression' => false]));

$builder->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('getGrammar')->andReturn(m::mock(Grammar::class, ['isExpression' => false]));

return [$builder, $parent, 'club_user', 'club_id', 'user_id', 'id', 'id', null, false];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Database\Query\Grammars\Grammar;
use Mockery as m;
use PHPUnit\Framework\TestCase;
use stdClass;

class DatabaseEloquentBelongsToManyWithoutTouchingTest extends TestCase
{
Expand All @@ -32,7 +33,9 @@ public function testItWillNotTouchRelatedModelsWhenUpdatingChild(): void
$parent->shouldReceive('getAttribute')->with('id')->andReturn(1);
$builder->shouldReceive('getModel')->andReturn($related);
$builder->shouldReceive('where');
$builder->shouldReceive('getGrammar')->andReturn(m::mock(Grammar::class, ['isExpression' => false]));
$builder->shouldReceive('getQuery')->andReturn(
m::mock(stdClass::class, ['getGrammar' => m::mock(Grammar::class, ['isExpression' => false])])
);
$relation = new BelongsToMany($builder, $parent, 'article_users', 'user_id', 'article_id', 'id', 'id');
$builder->shouldReceive('update')->never();

Expand Down
13 changes: 6 additions & 7 deletions tests/Database/DatabaseEloquentMorphToManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@ public function testAttachInsertsPivotTableRecord(): void
$query = m::mock(stdClass::class);
$query->shouldReceive('from')->once()->with('taggables')->andReturn($query);
$query->shouldReceive('insert')->once()->with([['taggable_id' => 1, 'taggable_type' => get_class($relation->getParent()), 'tag_id' => 2, 'foo' => 'bar']])->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);
$relation->expects($this->once())->method('touchIfTouching');

$relation->attach(2, ['foo' => 'bar']);
Expand All @@ -49,8 +48,7 @@ public function testDetachRemovesPivotTableRecord(): void
$query->shouldReceive('where')->once()->with('taggable_type', get_class($relation->getParent()))->andReturn($query);
$query->shouldReceive('whereIn')->once()->with('taggables.tag_id', [1, 2, 3]);
$query->shouldReceive('delete')->once()->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);
$relation->expects($this->once())->method('touchIfTouching');

$this->assertTrue($relation->detach([1, 2, 3]));
Expand All @@ -65,8 +63,7 @@ public function testDetachMethodClearsAllPivotRecordsWhenNoIDsAreGiven(): void
$query->shouldReceive('where')->once()->with('taggable_type', get_class($relation->getParent()))->andReturn($query);
$query->shouldReceive('whereIn')->never();
$query->shouldReceive('delete')->once()->andReturn(true);
$relation->getQuery()->shouldReceive('getQuery')->andReturn($mockQueryBuilder = m::mock(stdClass::class));
$mockQueryBuilder->shouldReceive('newQuery')->once()->andReturn($query);
$relation->getQuery()->getQuery()->shouldReceive('newQuery')->once()->andReturn($query);
$relation->expects($this->once())->method('touchIfTouching');

$this->assertTrue($relation->detach());
Expand Down Expand Up @@ -130,7 +127,9 @@ public function getRelationArguments(): array
$grammar = m::mock(Grammar::class);
$grammar->shouldReceive('isExpression')->with(m::type(Expression::class))->andReturnTrue();
$grammar->shouldReceive('isExpression')->with(m::type('string'))->andReturnFalse();
$builder->shouldReceive('getGrammar')->andReturn($grammar);
$builder->shouldReceive('getQuery')->andReturn(
m::mock(stdClass::class, ['getGrammar' => $grammar])
);

return [$builder, $parent, 'taggable', 'taggables', 'taggable_id', 'tag_id', 'id', 'id', 'relation_name', false];
}
Expand Down

0 comments on commit 24f16ba

Please sign in to comment.