Skip to content

Commit

Permalink
optimize findMany of BelongsToMany
Browse files Browse the repository at this point in the history
  • Loading branch information
imanghafoori1 committed Jan 20, 2023
1 parent 7a35c57 commit ba7b9c1
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 5 deletions.
8 changes: 3 additions & 5 deletions src/Illuminate/Database/Eloquent/Relations/BelongsToMany.php
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,8 @@ public function findMany($ids, $columns = ['*'])
return $this->getRelated()->newCollection();
}

return $this->whereIn(
$this->getRelated()->getQualifiedKeyName(), $this->parseIds($ids)
return $this->getRelated()->whereKey(
$this->parseIds($ids)
)->get($columns);
}

Expand Down Expand Up @@ -1153,8 +1153,6 @@ protected function guessInverseRelation()
*/
public function touch()
{
$key = $this->getRelated()->getKeyName();

$columns = [
$this->related->getUpdatedAtColumn() => $this->related->freshTimestampString(),
];
Expand All @@ -1163,7 +1161,7 @@ public function touch()
// the related model's timestamps, to make sure these all reflect the changes
// to the parent models. This will help us keep any caching synced up here.
if (count($ids = $this->allRelatedIds()) > 0) {
$this->getRelated()->newQueryWithoutRelationships()->whereIn($key, $ids)->update($columns);
$this->getRelated()->newQueryWithoutRelationships()->whereKey($ids)->update($columns);
}
}

Expand Down
78 changes: 78 additions & 0 deletions tests/Integration/Database/EloquentBelongsToManyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,48 @@ public function testFindMethod()
$this->assertCount(2, $post->tags()->findMany(new Collection([$tag->id, $tag2->id])));
}

public function testFindMethodStringyKey()
{
Schema::create('post_string_key', function (Blueprint $table) {
$table->string('id', 1)->primary();
$table->string('title', 10);
});

Schema::create('tag_string_key', function (Blueprint $table) {
$table->string('id', 1)->primary();
$table->string('title', 10);
});

Schema::create('post_tag_string_key', function (Blueprint $table) {
$table->id();
$table->string('post_id', 1);
$table->string('tag_id', 1);
});

$post = PostStringPrimaryKey::query()->create([
'id' => 'a',
'title' => Str::random(10),
]);

$tag = TagStringPrimaryKey::query()->create([
'id' => 'b',
'title' => Str::random(10),
]);

$tag2 = TagStringPrimaryKey::query()->create([
'id' => 'c',
'title' => Str::random(10),
]);

$post->tags()->attach(TagStringPrimaryKey::all());

$this->assertEquals($tag2->name, $post->tags()->find($tag2->id)->name);
$this->assertCount(0, $post->tags()->findMany([]));
$this->assertCount(2, $post->tags()->findMany([$tag->id, $tag2->id]));
$this->assertCount(0, $post->tags()->findMany(new Collection));
$this->assertCount(2, $post->tags()->findMany(new Collection([$tag->id, $tag2->id])));
}

public function testFindOrFailMethod()
{
$this->expectException(ModelNotFoundException::class);
Expand Down Expand Up @@ -1221,6 +1263,42 @@ public function postsWithCustomPivot()
}
}

class PostStringPrimaryKey extends Model
{
public $incrementing = false;

public $timestamps = false;

protected $table = 'post_string_key';

protected $keyType = 'string';

protected $fillable = ['title', 'id'];

public function tags()
{
return $this->belongsToMany(TagStringPrimaryKey::class, 'post_tag_string_key', 'post_id', 'tag_id');
}
}

class TagStringPrimaryKey extends Model
{
public $incrementing = false;

public $timestamps = false;

protected $table = 'tag_string_key';

protected $keyType = 'string';

protected $fillable = ['title', 'id'];

public function posts()
{
return $this->belongsToMany(PostStringPrimaryKey::class, 'post_tag_string_key', 'tag_id', 'post_id');
}
}

class Post extends Model
{
public $table = 'posts';
Expand Down

0 comments on commit ba7b9c1

Please sign in to comment.