You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TLDR: the "collection" cast is not able to handle mutations but AsCollection:class handles mutations correctly. These casts should both behave the same as how the AsCollection::class cast behaves.
Consider the following models.
// testAttr is a non-nullable json column with default = "[]"class MyAsCollectionModel extends Model
{
protected$casts = ["testAttr" => AsCollection::class];
protected$attributes = ["testAttr" => "[]"];
}
class MyCollectionModel extends Model
{
protected$casts = ["testAttr" => "collection"];
protected$attributes = ["testAttr" => "[]"];
}
The following are examples of the behaviour of the casted attribute for the two models respectively (in the tinker interactive console).
$x = MyAsCollectionModel::first();
// App\Models\MyAsCollectionModel {#6219// id: 1,// testAttr: "[]",// }$x->testAttr;
// Illuminate\Support\Collection {#6220// all: [],// }$x->testAttr[] = 'hi taylor';
// "hi taylor"$x->testAttr;
// Illuminate\Support\Collection {#6220// all: [// "hi taylor",// ],// }$x;
// App\Models\MyAsCollectionModel {#6219// id: 1,// testAttr: "["hi taylor"]",// }$x->testAttr = collect(["I'm a new collection"]);
// Illuminate\Support\Collection {#6221// all: [// "I'm a new collection",// ],// }$x->testAttr;
// Illuminate\Support\Collection {#6221// all: [// "I'm a new collection",// ],// }$x;
// App\Models\MyAsCollectionModel {#6219// id: 1,// testAttr: "["I'm a new collection"]",// }
vs
$x = MyCollectionModel::first();
// App\Models\MyCollectionModel {#6232// id: 1,// testAttr: "[]",// }$x->testAttr;
// Illuminate\Support\Collection {#6233// all: [],// }$x->testAttr[] = 'hi taylor';
// "hi taylor"$x->testAttr;
// Illuminate\Support\Collection {#6234// all: [],// }$x;
// App\Models\MyCollectionModel {#6232// id: 1,// testAttr: "[]",// }$x->testAttr = collect(["I'm a new collection"]);
// Illuminate\Support\Collection {#6235// all: [// "I'm a new collection",// ],// }$x->testAttr;
// Illuminate\Support\Collection {#6236// all: [// "I'm a new collection",// ],// }$x;
// App\Models\MyCollectionModel {#6232// id: 1,// testAttr: "["I'm a new collection"]",// }
As we can see, appending items to the collection doesn't behave the same for these casts. This seems to be because the "collection" cast is instantiating a new collection every time by JSON decoding the model's data, where as AsCollection doesn't do the same and is able to handle mutations correctly.
I believe that both of these casts should be behaving how AsCollection behaves.
I can provide a minimum recreation of this issue if required and might also endeavour to try creating a PR providing a fix.
Steps To Reproduce
Create a model with a json column that is getting cast to "collection", and an identical model which is casting the column to AsCollection::class. These casts will not behave the same as demonstrated in the description.
The text was updated successfully, but these errors were encountered:
As Laravel is an open source project, we rely on the community to help us diagnose and fix issues as it is not possible to research and fix every issue reported to us via GitHub.
If possible, please make a pull request fixing the issue you have described, along with corresponding tests. All pull requests are promptly reviewed by the Laravel team.
Ooh, that's interesting. And of course, this behaviour makes a lot of sense to me now given the history. I think that perhaps this nuance with the difference in mutability should be mentioned in the documentation. Should I open a PR against laravel/docs?
Laravel Version
10.43.0
PHP Version
8.3.2
Database Driver & Version
Postgres 16
Description
TLDR: the
"collection"
cast is not able to handle mutations butAsCollection:class
handles mutations correctly. These casts should both behave the same as how theAsCollection::class
cast behaves.Consider the following models.
The following are examples of the behaviour of the casted attribute for the two models respectively (in the tinker interactive console).
vs
As we can see, appending items to the collection doesn't behave the same for these casts. This seems to be because the "collection" cast is instantiating a new collection every time by JSON decoding the model's data, where as AsCollection doesn't do the same and is able to handle mutations correctly.
I believe that both of these casts should be behaving how AsCollection behaves.
I can provide a minimum recreation of this issue if required and might also endeavour to try creating a PR providing a fix.
Steps To Reproduce
Create a model with a json column that is getting cast to "collection", and an identical model which is casting the column to AsCollection::class. These casts will not behave the same as demonstrated in the description.
The text was updated successfully, but these errors were encountered: