-
-
Notifications
You must be signed in to change notification settings - Fork 224
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
Implement reference by class names #409
Conversation
You should retarget to 1.6.x |
It should be better now @greg0ire |
Deprecation::trigger( | ||
'doctrine/data-fixtures', | ||
'https://github.com/doctrine/data-fixtures/pull/409', | ||
'Argument $class of %s() will be mandatory in DoctrineDataFixtures 2.0.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This DoctrineDataFixtures
case is typically used for the bundle. I'd remove that name anyway:
'Argument $class of %s() will be mandatory in DoctrineDataFixtures 2.0.', | |
'Argument $class of %s() will be mandatory in 2.0.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. I also fixed the tests
This should help with some of the failures: #412 (and means you need to rebase) |
Rebased done |
|
Done, also updated the baseline |
There is an example call of |
Nice catch. I updated the doc. I didn't added |
Friendly ping @stof If you have time to take a new look :) |
I get no news from stof, Do you think it can be merged @greg0ire ? |
The requested changes have been addressed
Sure! Thanks @VincentLanglet ! |
You're welcome. Do you mind releasing the 1.6.0 version, or another PR/issue is needed first ? @greg0ire Also should I provide a PR on 2.x branch to solve the deprecation (into BC-break) I introduced ? |
Please do provide a 2.x PR. I'm AFK, but will try releasing from my phone. |
I'd like to report a shortfall in a scenario where class inheritance is at play. This is a problem when using Doctrine's inheritance mapping. Consider the example inheritance mentioned on Doctrine's page: class Person {}
class Employee extends Person {}
class Boss extends Person {} When you generate a lot of $this->setReference('person1', new Employee());
$this->getReference('person1', Person::class); This is because the fixtures are stored in an array indexed by the object's direct class name in I created my own solution to achieve the intended objective some time ago. A snippet of an abstract class that other Fixture-generating classes extend is below: <?php
use Doctrine\Bundle\FixturesBundle\Fixture;
abstract class AbstractFixture extends Fixture
{
/**
* @template T of object
* @param string $handle
* @param class-string<T> $expectedType
* @return T
*/
protected function getTypedReference(string $handle, string $expectedType): mixed
{
$object = $this->getReference($handle, $expectedType);
if (!$object instanceof $expectedType) {
throw new \InvalidArgumentException(sprintf('Handle %s is %s, not %s', $handle, get_debug_type($object), $expectedType));
}
return $object;
}
} Unless I'm missing something, using I would like to suggest the proposed change might need to be reconsidered. |
Duplicate key usage is one useful feature of this change. I see no reason to lost this when you can easily do
Which seems to be the right way to fetch the fixture since But maybe some others solutions exists which allow both to cohabit, like allowing to call
|
That's a bold assumption probably specific to your particular use case I see it exactly the other way:
Not true. While there would be differences, part of the API can overlap. That's the whole point of class inheritance. An example would be a comment system that accepts a Your fixtures may hold 100 references to random objects of The above is a simplified illustrative scenario explaining my point, but I have a comparable real-world use case. That's how I discovered the behaviour in the first place. I didn't make it up to be difficult in a random PR. Come to think of it, I could think of a use case where you are asking for an interface, not even a specific class. The
Yes: I'd suggest we could walk back the decision of making the |
You're still not developing how to keep the duplicate key feature. One way could be to change the storage from
to
If you call
WDYT ? |
That's because I truly believe it's not a good idea to allow duplicate keys.
I'd say that could work, depending on the implementation. My thoughts are:
This would allow one of the two scenarios:
Please note none of the variants discussed allow using duplicate keys if the class doesn't differ: $john = new Person();
$doe = new Person();
$registry->setReference('person', $john); // sets john
$registry->setReference('person', $doe); // overwrites john I repeat, I believe allowing duplicate keys lacks merit. |
That's your point of view and I disagree with it.
or
While I proposed solutions to allow both, you're just looking for solving your debatable use-case and remove another feature. This mindset doesn't encourage me to keep the discussion.
Feel free to provide one.
Not sure to understand.
Yes, that's I proposed when I talked about
There is no need for assertion if you're accessing
with the call
This would be the weirdest behavior to have:
This behavior is already the existing one if you look at the method data-fixtures/src/ReferenceRepository.php Lines 104 to 106 in dadd3c5
And if you're using the data-fixtures/src/ReferenceRepository.php Line 178 in dadd3c5
You'll get
|
Scalar primary key made of unique string value seems a simpler identifier than a composite key made of a non-unique string value and a non-unique class name, but hey, we both probably have good reasons for our views. Let's agree to disagree, not a big deal!
While the first option clearly isn't really an option, the other depends on the use case. Sometimes I know what instance I'm trying to get, sometimes I don't. I regularly let Symfony & Doctrine work out what object should be constructed when I use Doctrine's entity inheritance. The more frequent use case is when converting route parameters:
My use case is a documented fairly standard use of Doctrine's entity inheritance.
If I'm reading the code correctly,
Great. From your wording was not clear whether the
See my point about
I missed that, apologies. |
Allowing to pass a third parameter to the setReference was one of my first solution, but then I proposed another one which doesn't need this change. The fact we don't need a third parameter for
That's a debatable point. The first thing I have in mind was to allow call like
Maybe the solution would be to play with
|
I think iterating the whole array all the time could be slow with a large number of fixtures. Overnight I realised another downside: if you rely on a class name, you make the implicit assumption a fixture is an object. I can't say I do it myself, but the current system lets you store anything, including scalars. I think we should not throw that away. I came up with a slightly different approach: storing fixtures in a single array twice: under Have a look at a working demo, https://3v4l.org/HuZD6#v8.2.2 - I added inline comments to explain what I thought needs it. The end of the code, labeled as Part 3, shows some interesting improvements that I don't think would work with what this PR proposes. In the example, if you use duplicate What do you think? We could also take this chat to a more real-time medium. We're clearly both interested in finding a good solution. |
I was worried about this too, but since we're only iterating on the fixture with the name
The fixture is always an object according to the phpdoc |
Hmm, OK, it looks like that's the case. So scrap that "benefit" of being able to store scalars, it's probably a use case nobody needs. It just crossed my mind before I fell asleep. The rest of the PoC remains valid, though. |
We've got another issue with this PR. When we're calling Indeed, we have two EntityManagers configured. And it seems there is no way to indicate which one to create the reference on. Beforehand, it did not refer to the ObjectManager hence we could add references from different EntityManagers with no issue (maybe that was undesired but now we're missing a method to add a reference to a specific EntityManager). Our load method:
|
I don't fully understand the issue. This PR is 5 months old, that's not the right place to discuss about issues. |
@VincentLanglet The 2.0.x branch is now open. Do you want to continue your work there? |
Sure Ill take a look |
I made #464 |
Hi @greg0ire
Closes #408
I introduce a
$class
param in a BC way:In next major, the idea would be to make the class param mandatory.
This way, having two fixtures with the same name but different class would be allowed.