laravel-castable-data-transfer-object icon indicating copy to clipboard operation
laravel-castable-data-transfer-object copied to clipboard

Dealing with arrays of Value objects

Open arrilot opened this issue 3 years ago • 3 comments

Hello, what if we have a jsonb column addresses with [ {...}. {...}, {...} ] Is there any way to cast it to [ Address(...), Address(...), Address(...), ] ?

arrilot avatar Dec 07 '20 13:12 arrilot

Same here, I'd also like to do that.

danielbehrendt avatar Dec 07 '20 17:12 danielbehrendt

Hi @arrilot and @danielbehrendt, I can definitely see how that would be useful. It's currently only possible when the array of DTOs is nested within another DTO using the functionality provided by Spatie at https://github.com/spatie/data-transfer-object/#automatic-casting-of-nested-array-dtos.

To have the array as the top-level, we'd need to create an object to represent the array, and thankfully Spatie seems to have us covered there too, with their DataTransferObjectCollection class https://github.com/spatie/data-transfer-object/#working-with-collections, although I haven't needed that one myself yet so I'm not 100% sure how it works.

To get that working within the casts provided by this package, I think we'd just need to create a CastableDataTransferObjectCollection that implements Laravel's Castable interface, similar to how I've created the CastableDataTransferObject class. I don't have time to look into creating that right now, but I'd welcome a PR.

jessarcher avatar Dec 07 '20 23:12 jessarcher

@arrilot @danielbehrendt I've ported this package for POPOs using Symfony's serializer, which can support casting objects, dates and arrays.

https://github.com/morrislaptop/laravel-castable-object

I'd love to hear if this suits your needs! Basically it works like this

namespace App\Models;

use App\Values\Address;
use Illuminate\Database\Eloquent\Model;
use Morrislaptop\Caster\Caster;

/**
 * @property Address[] $addresses
 */
class User extends Model
{
    protected $casts = [
        'addresses' => Caster::class . ':' . Address::class . '[]',
    ];
}

I haven't tried it yet, but it could also potentially work for DTO's as well by adding a DataTransferObjectNormalizer into Symfony's Serializer. https://github.com/spatie/data-transfer-object/issues/93#issuecomment-738023471

@jessarcher would love your feedback on my package as well!

morrislaptop avatar Jan 25 '21 21:01 morrislaptop