Skip to content

Commit 3dca432

Browse files
Use queued job for "unsearching" when Scout queue is enabled (#471)
* Queue scout removals * Fix code doc * Undo new line * Fix style * Update src/Jobs/RemoveFromSearch.php Co-authored-by: Dries Vints <dries@vints.io> * Update src/Jobs/RemoveFromSearch.php Co-authored-by: Dries Vints <dries@vints.io> Co-authored-by: Dries Vints <dries@vints.io>
1 parent 33bbff0 commit 3dca432

File tree

3 files changed

+121
-1
lines changed

3 files changed

+121
-1
lines changed

src/Jobs/RemoveFromSearch.php

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
namespace Laravel\Scout\Jobs;
4+
5+
use Illuminate\Bus\Queueable;
6+
use Illuminate\Contracts\Queue\ShouldQueue;
7+
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
8+
use Illuminate\Queue\SerializesModels;
9+
10+
class RemoveFromSearch implements ShouldQueue
11+
{
12+
use Queueable, SerializesModels;
13+
14+
/**
15+
* The models to be removed from the search index.
16+
*
17+
* @var \Illuminate\Database\Eloquent\Collection
18+
*/
19+
public $models;
20+
21+
/**
22+
* Create a new job instance.
23+
*
24+
* @param \Illuminate\Database\Eloquent\Collection $models
25+
* @return void
26+
*/
27+
public function __construct($models)
28+
{
29+
$this->models = $models;
30+
}
31+
32+
/**
33+
* Handle the job.
34+
*
35+
* @return void
36+
*/
37+
public function handle()
38+
{
39+
if ($this->models->isNotEmpty()) {
40+
$this->models->first()->searchableUsing()->delete($this->models);
41+
}
42+
}
43+
44+
/**
45+
* Restore a queueable collection instance.
46+
*
47+
* @param \Illuminate\Contracts\Database\ModelIdentifier $value
48+
* @return \Illuminate\Database\Eloquent\Collection
49+
*/
50+
protected function restoreCollection($value)
51+
{
52+
if (! $value->class || count($value->id) === 0) {
53+
return new EloquentCollection;
54+
}
55+
56+
return new EloquentCollection(
57+
collect($value->id)->map(function ($id) use ($value) {
58+
return tap(new $value->class, function ($model) use ($id) {
59+
$model->forceFill([$model->getKeyName() => $id]);
60+
});
61+
})
62+
);
63+
}
64+
}

src/Searchable.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Illuminate\Database\Eloquent\SoftDeletes;
66
use Illuminate\Support\Collection as BaseCollection;
77
use Laravel\Scout\Jobs\MakeSearchable;
8+
use Laravel\Scout\Jobs\RemoveFromSearch;
89

910
trait Searchable
1011
{
@@ -80,7 +81,13 @@ public function queueRemoveFromSearch($models)
8081
return;
8182
}
8283

83-
return $models->first()->searchableUsing()->delete($models);
84+
if (! config('scout.queue')) {
85+
return $models->first()->searchableUsing()->delete($models);
86+
}
87+
88+
dispatch(new RemoveFromSearch($models))
89+
->onQueue($models->first()->syncWithSearchUsingQueue())
90+
->onConnection($models->first()->syncWithSearchUsing());
8491
}
8592

8693
/**
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace Laravel\Scout\Tests\Unit;
4+
5+
use Illuminate\Database\Eloquent\Collection;
6+
use Illuminate\Support\Facades\Config;
7+
use Laravel\Scout\Jobs\RemoveFromSearch;
8+
use Laravel\Scout\Tests\Fixtures\SearchableModel;
9+
use Mockery as m;
10+
use PHPUnit\Framework\TestCase;
11+
12+
class RemoveFromSearchTest extends TestCase
13+
{
14+
protected function setUp(): void
15+
{
16+
Config::shouldReceive('get')->with('scout.after_commit', m::any())->andReturn(false);
17+
}
18+
19+
protected function tearDown(): void
20+
{
21+
m::close();
22+
}
23+
24+
public function test_handle_passes_the_collection_to_engine()
25+
{
26+
$job = new RemoveFromSearch($collection = Collection::make([
27+
$model = m::mock(),
28+
]));
29+
30+
$model->shouldReceive('searchableUsing->delete')->with($collection);
31+
32+
$job->handle();
33+
}
34+
35+
public function test_models_are_deserialized_without_the_database()
36+
{
37+
$job = new RemoveFromSearch($collection = Collection::make([
38+
$model = new SearchableModel(['id' => 1234]),
39+
]));
40+
41+
$job = unserialize(serialize($job));
42+
43+
$this->assertInstanceOf(Collection::class, $job->models);
44+
$this->assertCount(1, $job->models);
45+
$this->assertInstanceOf(SearchableModel::class, $job->models->first());
46+
$this->assertTrue($model->is($job->models->first()));
47+
$this->assertEquals(1234, $job->models->first()->getScoutKey());
48+
}
49+
}

0 commit comments

Comments
 (0)