Skip to content

Commit

Permalink
[10.x] Do not touch BelongsToMany relation when using `withoutTouch…
Browse files Browse the repository at this point in the history
…ing` (#49798)

* Do not touch relation when ignore touching is enabled

* Add tests

* Apply styleci fixes
  • Loading branch information
mateusjunges authored Jan 24, 2024
1 parent cad642e commit 5f29723
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,10 @@ protected function guessInverseRelation()
*/
public function touch()
{
if ($this->related->isIgnoringTouch()) {
return;
}

$columns = [
$this->related->getUpdatedAtColumn() => $this->related->freshTimestampString(),
];
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace Illuminate\Tests\Database;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Mockery as m;
use PHPUnit\Framework\TestCase;

class DatabaseEloquentBelongsToManyWithoutTouchingTest extends TestCase
{
public function testItWillNotTouchRelatedModelsWhenUpdatingChild(): void
{
/** @var Article $related */
$related = m::mock(Article::class)->makePartial();
$related->shouldReceive('getUpdatedAtColumn')->never();
$related->shouldReceive('freshTimestampString')->never();

$this->assertFalse($related::isIgnoringTouch());

Model::withoutTouching(function () use ($related) {
$this->assertTrue($related::isIgnoringTouch());

$builder = m::mock(Builder::class);
$builder->shouldReceive('join');
$parent = m::mock(User::class);

$parent->shouldReceive('getAttribute')->with('id')->andReturn(1);
$builder->shouldReceive('getModel')->andReturn($related);
$builder->shouldReceive('where');
$relation = new BelongsToMany($builder, $parent, 'article_users', 'user_id', 'article_id', 'id', 'id');
$builder->shouldReceive('update')->never();

$relation->touch();
});

$this->assertFalse($related::isIgnoringTouch());
}
}

class User extends Model
{
protected $table = 'users';
protected $fillable = ['id', 'email'];

public function articles(): BelongsToMany
{
return $this->belongsToMany(Article::class, 'article_user', 'user_id', 'article_id');
}
}

class Article extends Model
{
protected $table = 'articles';
protected $fillable = ['id', 'title'];
protected $touches = ['user'];

public function users(): BelongsToMany
{
return $this->belongsToMany(User::class, 'article_user', 'article_id', 'user_id');
}
}

0 comments on commit 5f29723

Please sign in to comment.