I opened issue #18135 a while back regarding the casts property on custom pivot not being properly honored. This problem was fixed in 5.4.14 by using fromRawAttributes in the newPivot method of \Illuminate\Database\Eloquent\Model.
However, it was pointed out to me recently that the methods used to conveniently update/insert related models, particularly those for BelongsToMany relationships that allow the user to provide the attributes for the pivot (attach, sync, syncWithoutDetaching, save, updateExistingPivot etc.) do not honor the casts property on the custom pivot model.
Client model
class Client extends Model
{
public function networks()
{
return $this->belongsToMany(Network::class)
->using(ClientNetworkPivot::class)
->withPivot(['settings']);
}
}
Network model
class Network extends Model
{
public function clients()
{
return $this->belongsToMany(Client::class)
->using(ClientNetworkPivot::class)
->withPivot(['settings']);
}
}
ClientNetworkPivot
class ClientNetworkPivot extends Pivot
{
protected $casts = [
'settings' => 'array'
];
}
Steps
$client = Client::find(1);
$network = Network::find(1);
$client->networks()->attach($network, [
'settings' => ['This', 'is', 'an', 'array']
]);
$client->networks()->sync([
1 => ['settings' => ['This', 'is', 'an', 'array']]
]);
$client->networks()->syncWithoutDetaching([
2 => ['settings' => ['This', 'is', 'an', 'array']]
]);
$client->networks()->save($network, [
'settings' => ['This', 'is', 'an', 'array']
]);
$client->networks()->updateExistingPivot(3, [
'settings' => ['This', 'is', 'an', 'array']
]);
In all of the above examples I would expect to see the attributes array passed into each method, have their respective casts honored. In this instance I would have expected to see the ['This', 'is', 'an', 'array'] array for the settings cast to JSON and be inserted/updated in the database.
In every example above I get the same QueryException error:
Array to string conversion (SQL: insert into
client_network(client_id,created_at,network_id,settings,updated_at) values (1, 2017-03-28 09:36:02, 1, This, 2017-03-28 09:36:02))`
I second that there's an issue: In my case I'm using 2 models that use strings as IDs (varchar in database).
I'm attempting to use $myModel->theRelationship()->sync(["10212624279364351")] it attempts to save it as a string rather than respect the $keyType. I have even attempted it with the $casts.
Also if it's of any use when I create the relationship manually with ::create([...]); there's no problem at all
Thanks for opening this, @jrhenderson1988. Can confirm this behavior; it would be nice to have attach-ability on pivot models that respects the casts array.
Having the same issue.. Trying to set an array on the pivot model. Got the same error saving it.
Same issue here; I have an array on the pivot model, which I'm currently having to json_encode manually because of this. Would be great to just use casts like standard models.
Fixing in 5.5.
Most helpful comment
Fixing in 5.5.