symfony / maker-bundle

Symfony Maker Bundle
https://symfony.com/
MIT License
3.35k stars 406 forks source link

php bin/console make:crud cannot create relations between tables :: bug #401

Open nouraellm opened 5 years ago

nouraellm commented 5 years ago

Entities contain relations (OneToMany, ManyToOne) and when running php bin/console make:crud it doesn't recognize relations. when trying to access the route /new it throws an error. The view also doesn't return a form with related fields.

LeJeanbono commented 5 years ago

Can you provide an example ?

korkhau commented 4 years ago

Hi,

Can you provide an example ?

Catchable Fatal Error: Object of class App\Entity\MyClass could not be converted to string From https://stackoverflow.com/questions/52863790/symfony-makecrud-with-manytoone-relation there is a hint with __toString(). Can we have it in make:crud by default?

Working example to show name in select box:

    public function __toString()
    {
        return $this->getName();
    }

For default approach we can use $this->getId() as all entities have field id. Thanks

Harmo80 commented 4 years ago

Hello,

Yesterday, on a side project working with symfony 4.4.4, I choose to generate a CRUD for one of my entity with the make:crud command, but this entity contains a relation (ManyToOne) to another entityType which is really common in a relationnal database :) So, i encountered this same problem.

The crud generate a simple ->add('myRelation'), textField by default, so the form crash, because the entityType of the relation cannot be cast into a string. Catchable Fatal Error: Object of class App\Entity\MyTable could not be converted to string

I solved the problem in less than 10 minutes, not with a __toString() in my entity, but with a EntityType field in the form. This solution does not need modification in the entity, so it could be done automatically quite easily directly in the make:crud command. the field type EntityType already exists, and as we cannot know the specific field of "MyTable", the label associated could be the "id" by default.

          ->add('myRelation', EntityType::class, [
             'class' => MyTable::class,
             'query_builder' => function(MyTableRepository $myTableRepository) {
                 return $myTableRepository->createQueryBuilder('t')
                     ->orderBy('t.id', 'ASC');
             },
              'choice_label' => 'id'
          ]);

I was almost going to create a new issue, but fortunately, I found this already existing issue. ^_^ What do you think of this solution ?

If you are agree with this, I could try to implement this in a pull request !

Dallas62 commented 4 years ago

Hi, I use this issue to add that there is a line that exclude OneToMany relation from forms, any reasons ? https://github.com/symfony/maker-bundle/blob/ae95a2b7fa8272e75630c273396097074f23e03f/src/Doctrine/EntityDetails.php#L67 Thanks

ckrack commented 4 years ago

@Harmo80 This solution is not really universal. You usually want a field like name or title to be the displayed value (return value of __toString()), instead of the id. We could modify the Entity and add a __toString() method if it is missing. This could be by guessing and should emit a warning.

It checks for columns named 'name', 'title', 'description', 'subject', 'keywords' and finally 'id' to use as the string representation.

This has been done before: https://symfony.com/legacy/doc/forms/1_4/en/11-Doctrine-Integration#chapter_11_the_crud_generator (search for toString).

Or we accept failing tests in this case and just show a warning like:

The related Entity 'SweetFood' can not be cast to String. Please add a __toString() implementation to App\Entity\SweetFood.

The same behavior should be implemented in make:form.

@Dallas62 one-to-many relations are not added - they should be added to the inverse side forms as many-to-one.

LeJeanbono commented 4 years ago

@ckrack I like the first solution but with a warning that indicate how to change the label (editing __toString())