martin-georgiev / postgresql-for-doctrine

PostgreSQL enhancements for Doctrine. Provides support for advanced data types (json, jssnb, arrays), text search, array operators and jsonb specific functions.
https://packagist.org/packages/martin-georgiev/postgresql-for-doctrine
MIT License
353 stars 42 forks source link

arrays in Symfony Forms #74

Open tacman opened 3 years ago

tacman commented 3 years ago

I'm trying to implement a data transformer to save integer[] values in a postgres database using the bundle.

// some entity with tags
/**
 * @ORM\Column(type="integer[]", nullable=true)
 */
    protected $tagIds;

    public function getTagIds(): array
    {
        return $this->tagIds ?: [];
    }

    public function setTagIds($tagIds): self
    {
        $this->tagIds = $tagIds;
        return $this;
    }

I'd like to add these tags Id via a custom form type (for now, just a string of comma-delimited integers, for this issue report)

        $builder
            ->add('tagIds', TagIdsType::class, [
                'required' => false,
                'help' => 'comma-delimited tag ids',
            ])
        ;

The TagIdsType, following the instructions from https://symfony.com/doc/current/form/create_custom_field_type.html

class TagIdsType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('tag_string', TextareaType::class, [
                'help' => 'comma-delimited tag ids',
            ])
        ;
        $builder->get('tag_string')->addModelTransformer(new TagIdsTransformer());

Finally, the TagIdsTransformer:

// TagIdsTransformer.php
namespace App\Form\DataTransformer;

use App\Entity\TaggableInterface;
use Symfony\Component\Form\DataTransformerInterface;

class TagIdsTransformer implements DataTransformerInterface

{
    public function transform($taggableEntity)
    {
        /** @var TaggableInterface $taggableEntity */
        return $taggableEntity ? implode(',', $taggableEntity->getTagIds()): '';
    }

    public function reverseTransform($tagsAsString)
    {
        dump($tagsAsString);
        $tagsAsArray =  array_map(fn ($idAsString) => (int)$idAsString, explode(',', $tagsAsString));
        dump($tagsAsArray);
        return $tagsAsArray;
    }
}

When I fill out the form with a string of comma-delimited integers, it fails with the message

One or more of items given doesn't look like valid. {"tag_string":[3]} array

The transform and reverseTransform appear to be returning the right values, so I'm not sure where the error is. Obviously, I don't want tag_string, it's not part of the entity.

I'm posting here because if someone provides a solution, I can submit a PR to the documentation, as I imagine this can help others as well. Thanks.

martin-georgiev commented 1 year ago

Did you find a solution to your use-case? Can this issue be closed?

tacman commented 1 year ago

I didn't find a solution, but I'm likely to try again this week.

trading-developer commented 1 year ago

I didn't find a solution, but I'm likely to try again this week.

Did you find a solution to your use-case? Can this issue be closed?

fstronin commented 1 year ago

@tacman , hi! Try to grep the validator component for the string "One or more of items given doesn't look like valid" because it seems that there is some validator that can not process the input data correctly. Have you assigned any constraints to your form?