Say we have a Post model, with a boolean published attribute, and a model factory to seed our table as follows:
$factory->define(App\Post::class, function (Faker\Generator $faker) {
$tile = $faker->realText(50);
$date = $faker->dateTime;
return [
'title' => $tile,
'body' => $faker->realText(500),
'published' => $faker->boolean(80),
'created_at' => $date,
'updated_at' => $date
];
});
Let's say we will seed 10 records.
public function run()
{
factory(App\Article::class, 10)->create();
}
If we tried to exclude unpublished records within the toSearchableArray() method, as suggested:
public function toSearchableArray()
{
if (! $this->published) {
return[];
}
// ...
}
When seeding the posts table, instead of ignoring unpublished records by returning an empty array, scout will keep asking the model factory for a published model.
For example, if two of the seeded records were randomly unpublished, scout would index all 10 records (instead of 8) anyway, replacing the unpublished ones by a new model factory (with a published set attribute). Thus causing to have two inexistent (on our table) records in the algolia index. Quite confusing.
The "neatest" way around this I could come up with, was to listen to the saved/updated events (saving/updating won't cut it) in the model's boot method.
protected static function boot()
{
static::saved(function ($model) {
if (! $model->published) {
$model->unsearchable();
}
});
static::updated(function ($model) {
if (! $model->published) {
$model->unsearchable();
}
});
parent::boot();
}