-
Notifications
You must be signed in to change notification settings - Fork 46
Open
Description
Bug: Attaching an array of models causes TypeError: Illegal offset type
When passing an array of model instances to attach, it throws:
TypeError: Illegal offset type
Example:
$user->rights()->attach([Right::find(1), Right::find(2)]);Cause
The issue lies in the getIdsWithAttributes method:
elseif (is_array($id)) {
foreach ($id as $key => $attributesArray) {
if (is_array($attributesArray)) {
$ids[$key] = array_merge($attributes, $attributesArray);
} else {
$ids[$attributesArray] = $attributes;
}
}
} Here, $id is an array of models, so $attributesArray is actually a model instance of Right.
When the code runs:
$ids[$attributesArray] = $attributes;it fails because $attributesArray is an object, not a scalar key.
Suggested Fix
Before using $attributesArray as an array key, you should check whether it’s a Model instance and extract its key.
Alternatively, consider adapting Laravel’s own implementation from parseIds($value):
private function parseIds($value)
{
if ($value instanceof Model) {
return [$value->{$this->relatedKey}];
}
if ($value instanceof EloquentCollection) {
return $value->pluck($this->relatedKey)->all();
}
if ($value instanceof BaseCollection || is_array($value)) {
return (new BaseCollection($value))
->map(fn ($item) => $item instanceof Model ? $item->{$this->relatedKey} : $item)
->all();
}
return (array) $value;
}This approach gracefully handles model instances, arrays, or collections.
A small tweak like this inside getIdsWithAttributes() would solve the problem entirely.
Metadata
Metadata
Assignees
Labels
No labels