Just in case anyone is looking for an answer; I spent some time debugging because I ran into the same issue:
The reason for this is that in the example above toSearchableArray() always returns an empty array. $this->published cannot be true because no model is loaded at the time Scout is calling this method.
Because it uses this method to gather the searchable columns it must not be dynamic.
An empty array returned by toSearchableArray() causes the DatabaseEngine not finding any column keys to be included in the query, resulting in returning everything.
I ran into it because I used it like in the docs (https://laravel.com/docs/12.x/scout#configuring-searchable-data)
public function toSearchableArray(): array
{
return $this->toArray();
}
Because there is no loaded model, there are no attribute keys to be found via $this->toArray() thus an empty array is returned.
I think the docs are actually misleading by mentioning $this->toArray() at all because it does not work like this with the database engine. I had to change it to an explicit definition, like in all the other examples in the docs, so it can find the keys at all times; it must not be dynamic.
public function toSearchableArray(): array
{
return [
'id' => $this->id,
'name' => $this->name,
];
}
To make sure only published posts are added to the index the shouldBeSearchable() method should be used as stated in the docs:
https://laravel.com/docs/12.x/scout#conditionally-searchable-model-instances
In short: make sure toSearchableArray() returns an array with column keys explicitly, not dynamically.