The issue doesn't seem to be casting, but rather loose comparison on name when using ->where() on the resulting Collection vs ->where() on the Database layer. Compare:
$this->players->where('name', $value)->count();
In the above, $this->players will be a Collection of all Player records from the Database associated with $this (another Model I assume). This is the equivalent of something like:
$players = collect([
['id' => 1, 'name' => '123'],
['id' => 2, 'name' => '234'],
// ...
]);
$players->where('name', '123')->count(); // 1
$players->where('name', '000123')->count(); // 1 (That's odd...)
$players->where('name', '234')->count(); // 1
$players->where('name', '345')->count(); // 0
// ... Ect etc.
In the above examples, you can see that the "loose" comparison on name, using '00123' and '123' both returns 1. This is problematic, as the Database can handle '000123' and '123' as distinct entities, but querying against a Collection cannot.
To get around this, we should query directly against the Database, using the players method instead of property (() denotes a method, lack of () denotes a property):
$query = $this->players()->where('name', $value); // Omitted the `count()` for now
At this point in time, $query is a Database Query (Builder instance). We can see the SQL that would be executed by calling ->toSql():
dd($query->toSql());
// SELECT * FROM players WHERE related_id = ? AND name = ?
(Replace related_id with whatever $this represents in the original question).
Chaining the method ->count() will execute this as a SELECT count(...) ... query, instead of counting the length of the Collection.
So, to put it all together; Query directly against the Database using ->players(), execute a ->count() or ->exists() query:
return !$this->players()->where('name', $value)->count(); // 0 or # > 1
// OR
return !$this->players()->where('name', $value)->exists(); // true or false
namein your database?(DESCRIBE players;, or post yourmigration). If the database can handle00123and123as separate entities, and you don't haveprotected $casts = ['name' => 'integer'];on yourPlayermodel, then all should be well. Sidenote,$this->players->where()doesn't directly query the database, but rather the resultingCollectionof$this->players()->get(). This might be better as$this->players()->where('name', $value)->count()(->players()vs->players, without the()).->playersand->players().->players(without the()) will execute$this->players()->get()behind the scenes, which results in aCollection, which has a->where()method, which searches against the records in thatCollectionand not the Database.->players(), with the(), is a Query, which searches directly against the DB. You'd then execute->get(),->count(), etc, like$this->players()->where(...)->get()players->get()when debugging, because the players were already implicitly got. Thanks again. (And if you copy/paste your comment to an answer, I'll accept it.)->players->get()can work, but you need to pass something to->get(), like->players->get('name'). See laravel.com/docs/8.x/collections#method-get