Replies: 2 comments
-
Additional Comment for GitHub IssueAfter further investigation, I discovered that the root cause of this issue is related to Eloquent's casting mechanism. In my case, the As a temporary workaround, I extended the namespace App\Relations;
use Illuminate\Database\Eloquent\Relations\HasMany;
class BinaryHasMany extends HasMany
{
public function addEagerConstraints(array $models)
{
$keys = $this->getEagerModelKeys($models);
if ($this->parent->getKeyType() === 'binary') {
$keys = array_map(function ($key) {
return $key; // Already binary from getRawOriginal
}, $keys);
}
$whereIn = $this->whereInMethod($this->parent, $this->localKey);
if (!empty($keys)) {
$this->whereInEager($whereIn, $this->foreignKey, $keys, $this->getRelationQuery());
}
}
protected function getEagerModelKeys(array $models)
{
$keys = [];
foreach ($models as $model) {
if (!is_null($value = $model->getRawOriginal($this->localKey))) {
$keys[] = $value; // Fetch raw binary value before casting
}
}
return array_values(array_unique($keys));
}
} This resolves the issue by bypassing the cast, but it’s a workaround rather than a proper fix. Ideally, Eloquent should handle binary keys natively in |
Beta Was this translation helpful? Give feedback.
-
I understand your surprise, but on the other hand, there is nowhere in the docs which says I also couldn't find any code which handle this So I guess this is, unfortunately, an unsupported case. My suggestion would be to send a PR - or create a 3rd-party package - to handle this use-case. Covering not just the |
Beta Was this translation helpful? Give feedback.
-
Laravel Version
11
PHP Version
8.2
Database Driver & Version
10.11.2-MariaDB
Description
When using Eloquent’s
::with
method to eagerly load aHasMany
relationship with binary primary/foreign keys, the generatedWHERE IN
clause in the relationship query uses string representations of the keys instead of their binary form. This causes the query to return no results, even though the data exists in the database and direct queries with binary values work correctly.This issue arises because the
HasMany
relation’saddEagerConstraints
method retrieves the parent model’s key viagetEagerModelKeys
, which seems to cast or process the binary key (keyType = 'binary'
) as a string. When this string value is passed to theWHERE IN
clause, it fails to match the binary column in the related table.Steps To Reproduce
Steps to Reproduce
HasMany
relationship using binary keys:Expected Behavior
blocks
relationship should load correctly, returning the relatedBlock
records.property_id
in theWHERE IN
clause to match the binary column in theblocks
table.Actual Behavior
blocks
relationship returns an empty collection.WHERE IN
clause, which doesn’t match the binaryproperty_id
column:Additional Context
::with
:IN
(string) andWHERE
(binary) conditions, causing no matches:"select * from `blocks` where `blocks`.`property_id` in ('01JNCAQ3VZEK2ANMN38ZMWBY9V') and `property_id` = [binary_value]"
Possible Cause
The issue likely stems from
HasMany::getEagerModelKeys
, which retrieves the parent model’sproperty_id
as a string rather than preserving its binary form, despitekeyType = 'binary'
. This string value is then passed towhereIn
, leading to a type mismatch with the binary column.Suggested Fix
Modify
HasMany::addEagerConstraints
to respect thekeyType
of the parent model and ensure binary keys are preserved. For example:Alternatively, provide a way to disable or customize the automatic
WHERE IN
constraint when a closure is provided, allowing full control over the relationship query.Workaround
As a temporary workaround, I’ve resorted to manually loading the relationship:
However, this bypasses Eloquent’s eager loading benefits and isn’t ideal for larger applications.
Additional Notes
This issue may affect other relationship types (e.g.,
BelongsToMany
) with binary keys. I’d be happy to assist further in debugging or providing a PR if needed.Beta Was this translation helpful? Give feedback.
All reactions