Code Monkey home page Code Monkey logo

Comments (17)

Holicz avatar Holicz commented on June 5, 2024 8

Sorry to revive this old thread, but I have better solution than the custom UuidEntityType proposed by @umpirsky (thanks for that btw) and people reading this thread may be interested.

Only thing you have to do is pass your entity repository into the form type and pass choices inside with $repository->findAll();.

Like this:

final class SomeFormType extends AbstractType
{
    private SportRepository $sportRepository;

    public function __construct(
        SportRepository $sportRepository
    ) {
        $this->sportRepository = $sportRepository;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add(
                'sport',
                EntityType::class,
                [
                    'required' => true,
                    'class' => Sport::class,
                    'choice_label' => 'name',
                    'label' => 'Sport',
                    'choices' => $this->sportRepository->findAll(),
                ]
            );
    }
}

from uuid-doctrine.

ramsey avatar ramsey commented on June 5, 2024 2

Is the form submitting a UUID and attempting to do a database lookup based on that ID? If so, check to make sure the form isn't using the string version of the UUID when trying to do the database lookup. It needs to use the binary version of the UUID.

from uuid-doctrine.

umpirsky avatar umpirsky commented on June 5, 2024 2

I found a workaround by creating custom UuidEntityType, here is the gist.

@ramsey I'd like to contribute this, but not sure where it belongs? ORMQueryBuilderLoader.php knows only about uuid and guid, but not about uuid_binary_ordered_time. Do you think it's worth adding optionl Symfony compatibility layer to this package?

from uuid-doctrine.

ramsey avatar ramsey commented on June 5, 2024

@fmonts Were you able to solve this?

from uuid-doctrine.

juliusstoerrle avatar juliusstoerrle commented on June 5, 2024

I got the same Problem. The Form is using the string and not the binary Version of the UUID but i wasn't yet able to change that.

from uuid-doctrine.

ramsey avatar ramsey commented on June 5, 2024

@juliusstoerrle I'll reopen the issue, but I need more information in order to help solve this. Can you put together a short, reproducible example that you can paste here?

from uuid-doctrine.

juliusstoerrle avatar juliusstoerrle commented on June 5, 2024

Jep I will

from uuid-doctrine.

juliusstoerrle avatar juliusstoerrle commented on June 5, 2024

** Do you just want the classes or a complete symfony set up?**


In my controller i generate just a basic form via the form builder to edit/create a MembershipStatusTransition object. It contains the ID as a hidden field and the $from field as a EntityType.

The Objects for the example:
The Transition objects holds the Membership Object in a ManyToOne Relationship aka. is the many side.
It actually has a to (MembershipStatus) property as well but I removed it for this example.

<?php
declare(strict_types = 1);

namespace Core\Domain\Model\MembershipStatus;

use Core\Domain\Service\UuidTimeOrderedGenerator;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="membershipstatus_transition")
 */
class MembershipStatusTransition
{
    /**
     * @var \Ramsey\Uuid\Uuid
     *
     * @ORM\Id
     * @ORM\Column(type="uuid_binary_ordered_time")
     */
    private $id;

    /**
     * @var MembershipStatus
     *
     * @ORM\ManyToOne(targetEntity="Core\Domain\Model\MembershipStatus\MembershipStatus")
     */
    private $from;

    public function __construct()
    {
        $generator = new UuidTimeOrderedGenerator();
        $this->id = $generator->generate();
    }

    /**
     * @return \Ramsey\Uuid\Uuid
     */
    public function getId(): \Ramsey\Uuid\Uuid
    {
        return $this->id;
    }

    /**
     * @param \Ramsey\Uuid\Uuid $id
     */
    public function setId(\Ramsey\Uuid\Uuid $id): void
    {
        $this->id = $id;
    }

    /**
     * @return MembershipStatus
     */
    public function getFrom(): MembershipStatus
    {
        return $this->from;
    }

    /**
     * @param MembershipStatus $from
     */
    public function setFrom(MembershipStatus $from): void
    {
        $this->from = $from;
    }

}

The Membership Status is what gets selected in the ManyToOne relation. It consist of a UUID as PK plus some Metadata (Title, Description etc.)


<?php
declare(strict_types = 1);

namespace Core\Domain\Model\MembershipStatus;

use Core\Domain\Service\UuidTimeOrderedGenerator;
use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\UuidInterface;

/**
 * @ORM\Entity
 * @ORM\Table(name="membershipstatus")
 */
class MembershipStatus
{
    /**
     * @var \Ramsey\Uuid\Uuid
     *
     * @ORM\Id
     * @ORM\Column(type="uuid_binary_ordered_time")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=100, nullable=false)
     */
    private $title;

    public function __construct()
    {
        $generator = new UuidTimeOrderedGenerator();
        $this->id = $generator->generate();
    }

    /**
     * @return UuidInterface
     */
    public function getId(): UuidInterface
    {
        return $this->id;
    }

    /**
     * @param UuidInterface $id
     */
    public function setId(UuidInterface $id): void
    {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getTitle(): ?string
    {
        return $this->title;
    }

    /**
     * @param string $title
     */
    public function setTitle(string $title): void
    {
        $this->title = $title;
    }

}

from uuid-doctrine.

ramsey avatar ramsey commented on June 5, 2024

Thank you for the details. I'll take a look and see what I can find.

from uuid-doctrine.

mintobit avatar mintobit commented on June 5, 2024

@juliusstoerrle Hey. What symfony version are you using? Posting Controller (or whatever place you are using it) code and Form definition would help as well.

This and this might help. I'd also suggest posting this issue to symfony repo, makes it more likely someone will help.

from uuid-doctrine.

Jean85 avatar Jean85 commented on June 5, 2024

If the issue is that it uses a string version for the uuid instead of the binary one, you should either use data transformers, or specify a custom query builder object for the query, using the querybuilder form option, see: https://symfony.com/doc/current/reference/forms/types/entity.html#query-builder

from uuid-doctrine.

juliusstoerrle avatar juliusstoerrle commented on June 5, 2024

Sorry for being offline for so long,
Symfony Version is 3.3.6; Doctrine/Orm is 2.5.10;

@Jean85 I tried various forms of data transformers non worked, i tested the form with a specified custom query builder with no change as well, would you be able to please make a short example how i should set up the builder?

I think this issue might has the same roots as #18, but I'm not yet sure on how to use that solution in a symfony form?

from uuid-doctrine.

juliusstoerrle avatar juliusstoerrle commented on June 5, 2024

One of the form definitions:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('id',HiddenType::class, ['disabled' => true])
        ->add(
            $builder
                ->create('from', EntityType::class, [
                    'class' => 'Core\Domain\Model\MembershipStatus\MembershipStatus',
           
                    'choice_label' => 'title'
                ])
                //->addViewTransformer(new StringToStatusTransformer($this->em
    ));
    $builder->get('id')->addModelTransformer(new StringToUuidTransformer());
    dump($builder);
}

The StringToUuidTransformer is able to transform a UUID inside TextField but not when it is inside an drop down (select)

from uuid-doctrine.

meistersoda avatar meistersoda commented on June 5, 2024

Is there any update? I have the same problem.

$builder->add('in_reply_to', EntityType::class, ['class' => 'CommentsBundle:Comment'])

where Comment is referenced by an uuid_binary_ordered_time

I am serializing the uuid as a string and want to pass it with json to the form as 'in_reply_to' parameter - also as a json string.

What is the best practice to do this? I want to achive something like this

{
        "comment": "Test",
        "in_reply_to": "533b05de-ebd6-11e7-92bb-0220642b0501"
}

Or is the only way to pass it with TextType and validate with a custom validator?

from uuid-doctrine.

ramsey avatar ramsey commented on June 5, 2024

I’ve been unable to reproduce this issue. I will ask around and see if others are able to help.

from uuid-doctrine.

meistersoda avatar meistersoda commented on June 5, 2024

It seems related to #18

If I call
$this->getDoctrine()->getManager()->getRepository('CommentsBundle:Comment')->findOneById($request->request->get('in_reply_to'))
symfony generates a query with id = "" ... and seems to use bytes.

Validation by EntityType creates a query with id IN (...) and does not seem to use bytes.
Maybe its caused by MariaDB.

from uuid-doctrine.

pluk77 avatar pluk77 commented on June 5, 2024

ORMQueryBuilderLoader.php knows only about uuid and guid, but not about uuid_binary_ordered_time.

Seeing that the Doctrine Bridge only caters for a limited amount of types for which it is using the ConvertToDatabaseType() function, the correct solution is probably to open an issue and create a PR for that code on the symfony side and ensure that all non-integer types are properly handled.

As a work-around, if the application only uses one type of uuid, a solution might be to add both uuid and uuid_binary doctrine types and point them both to the same Ramsey class. That way the ORM bridge works and UuidBinaryType::NAME can still be used as the 3rd parameter in QueryBuilder::setParameter().

If this is a proper solution, a PR to update the Ramsey documentation might be all that is required.

ramsey_uuid_doctrine.yaml:

doctrine:
    dbal:
        types:
            uuid: 'Ramsey\Uuid\Doctrine\UuidBinaryType'
            uuid_binary: 'Ramsey\Uuid\Doctrine\UuidBinaryType'

@ramsey Can you think of any downsides to sticking to the uuid name and pointing it to the UuidBinaryType?

from uuid-doctrine.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.