Just a small issue, but something I came across and wanted to highlight. In short, groupBy()
on an \Illuminate\Database\Eloquent\Collection
should return a new \Illuminate\Support\Collection
so we can successfully call only()
(and other methods) on it.
Say we get a set of models from the database which returns an \Illuminate\Database\Eloquent\Collection
.
$media = File::all();
Then we want to groupBy()
that collection, which returns a new Eloquent collection with the specified attributes as keys.
$media = $media->groupBy('groupkey');
"key1" => [
"value",
"value",
"value"
],
"key2" => [
"value",
"value",
"value"
],
"key3" => [
"value",
"value",
"value"
],
Following that, we call $media->only(['key2', 'key3'])
which throws a BadMethodCallException: Method getKey does not exist.
as it tries to use the model's keys. Since we did a groupBy()
there are no immediate models as child, only the keys we extracted.
If we put a toBase()
in between, we get a regular collection and the result we expected, so why not return a regular collection in the first place?
$media->groupBy('groupkey')->toBase()->only(['key2', 'key3'])
This is because groupBy()
(and basically all Collection methods) return a new static
docs. This is done to ensure that all classes extending Illuminate\Support\Collection
(like an Eloquent collection) can then continue to call methods of that child class.
In your case it is unfortunate because you want the functionality of the base collection instead of the Eloquent collection (overwritten only()
method). I think ->toBase()
is a good compromise to still be able to access functionality of the base (illuminate/support) collection.
Personally I don't think it should return a regular collection, because you would loose the ability to chain specific Eloquent collection methods after that.
Most helpful comment
This is because
groupBy()
(and basically all Collection methods) return anew static
docs. This is done to ensure that all classes extendingIlluminate\Support\Collection
(like an Eloquent collection) can then continue to call methods of that child class.In your case it is unfortunate because you want the functionality of the base collection instead of the Eloquent collection (overwritten
only()
method). I think->toBase()
is a good compromise to still be able to access functionality of the base (illuminate/support) collection.Personally I don't think it should return a regular collection, because you would loose the ability to chain specific Eloquent collection methods after that.