Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Auto populate ModelFactory::getDefaults() based on doctrine mapping #100

Closed
MGDSoft opened this issue Dec 25, 2020 · 8 comments
Closed

Auto populate ModelFactory::getDefaults() based on doctrine mapping #100

MGDSoft opened this issue Dec 25, 2020 · 8 comments
Labels
enhancement New feature or request

Comments

@MGDSoft
Copy link

MGDSoft commented Dec 25, 2020

Hi @kbond thx for this bundle!

Two years ago I created a similiar bundle https://github.com/MGDSoft/FixturesGeneratorBundle.
This bundle can create auto defaultValues and create fixtures for all entities with a single command (with his dependencies), it would be great if that features was in this bundle too.
I can help with this if you are agree.

@kbond
Copy link
Member

kbond commented Dec 28, 2020

Hey @MGDSoft, glad you like the bundle!

#15 I think would address "create fixtures for all entities with a single command" so I'd love some help on that.

For the auto default values, this would be really neat. I'm trying to think on how it would work:

  1. I'd only like non-nullable values to have a default auto set.
  2. For non-relation fields, setting a default value via faker should be easy enough (ie $faker->sentence() for string, $faker->randomNumber() for integer, $faker->dateTime() for datetime, etc...)
  3. For non-null relations this might get a bit more difficult as the factory might not exist for the relation (if not using --all). What do you think?

@kbond kbond added the enhancement New feature or request label Mar 4, 2021
@kbond kbond changed the title Some ideas for rapid development Auto populate ModelFactory::getDefaults() based on doctrine mapping Mar 4, 2021
@benblub
Copy link
Contributor

benblub commented May 27, 2021

👀 is this feature in building?

@kbond
Copy link
Member

kbond commented May 27, 2021

Not yet by me anyway - my schedule's pretty full currently.

@benblub
Copy link
Contributor

benblub commented May 27, 2021

mhh i like this idea :/

some dummy/inspire code/test

$classMetaData = $entityManager->getClassMetadata(Product::class);

$defaultsArray = [];
$fakerTypes = [
    'integer' => faker()->randomNumber(),
    'string' => faker()->sentence(),
    'date' => faker()->dateTime(),
];

foreach ($classMetaData->fieldMappings as $property) {
    // create with faker
    if (!$property['nullable']) {
        $defaultsArray[] = $fakerTypes[$property['type']];
    }
}

foreach ($classMetaData->associationMappings as $classname => $values) {
    // Check Factory exist and create or skip? class_exists($classname.'Factory')
}
/**
 * @ORM\Entity
 * @ORM\Table(name="products")
 */
class Product
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected int $id;
    /**
     * @ORM\Column(type="string", nullable=true)
     */
    protected string $name;

    /**
     * @ORM\Column(type="date")
     */
    protected DateTime $someDate;

    /**
     * @ORM\Column(type="array")
     */
    protected array $someArray = [];

    /**
     * @ManyToOne(targetEntity="Category")
     * @JoinColumn(name="category_id", referencedColumnName="id")
     */
    protected Category $category;


    public function getId()
    {
        return $this->id;
    }

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

    public function setName($name)
    {
        $this->name = $name;
    }

@kbond
Copy link
Member

kbond commented May 27, 2021

Thanks, yes, that's basically what I was thinking. Pretty easy for the scalar doctrine types. It gets more complicated for the non-nullable ManyToOne relationships. #162 allows us to now see if a factory exists already so I think auto-creating if it doesn't exist is good idea.

I think this should be an opt-in flag on the maker command (ie make:factory --auto-defaults).

@benblub
Copy link
Contributor

benblub commented May 28, 2021

Its need take care of Asserts too. As examble a string $email with an Assert/Email must use faker()->email() instead of faker()->sentence(). And you think about it its need also to take care of the fieldNames.
.. a string

  • can be an email
  • can be an company
  • can be an country
  • ...

for strings we can look for

  • Constraints (Email, Url, ...)
  • Fieldnames which match some List like country ..
  • default values which not null|''
  • an faker()->sentence() as fallback

i have to investigate on relationships and yes auto-creating for non exist sounds like a good solution.

@benblub
Copy link
Contributor

benblub commented Jun 29, 2021

I think this Issue can be closed?

@kbond
Copy link
Member

kbond commented Jun 29, 2021

Closed with #173.

@kbond kbond closed this as completed Jun 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

3 participants