Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.6k
[DoctrineBridge] Add a way to select the repository used by the UniqueEntity validator#15002
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
if (!($supportedClass === $className || is_subclass_of($className, $supportedClass))) { | ||
throw new ConstraintDefinitionException(sprintf( | ||
"Unable to use the given '%s' repository for the '%s' entity.", |
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.
In Symfony, we are quoting with"
instead of'
.
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.
I must have done the same ashere I guess.
There are some other occurrences of "bad" quoting messages in Symfony components.
Anyway, fixed. :)
This PR was merged into the 2.3 branch.Discussion----------Fix quoting style consistency.| Q | A| ------------- | ---| Bug fix? | no| New feature? | no| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | -| License | MIT| Doc PR | -This is a really minor change with reference to [this comment](#15002 (comment)).If it's fine, [those changes](symfony:2.7...ogizanagi:fix_quoting_style/2.7) for 2.7 will follow up too.Commits-------57d30f9 Fix quoting style consistency.
lemoinem commentedSep 15, 2015 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Hey, I also hit this bug, very similar use case too... I was in the process of developing a new PR to fix it... However, I had a slightly different approach in mind, and thought it would be nice to have your feedback regarding this. If you feel like this should be in a separate PR, please, just say so. I will remove my comment and submit it as a separate [RFC] issue. If you’re interested, thank you very much, however (disclaimer) brace yourself, it’s a rather long post! 😉 PS: Shortcut: I created a RFC (#16969) issue and two PRs (#16978,#16981) to provide a better understanding of my design. If you checked these, you can skip this post entirely. SuggestionOn thenaming things is hard front, I was thinking about using I was actually thinking it could be an information many Class Constraints could need. So I was thinking of moving this outside of the Doctrine Bridge and inside the Validator Component itself. I thought we could create a new Regarding the UniqueEntity Validator, we would, then, use the Constraint ‘s DiscussionI think it would provide a more generic approach (any constraint implementing the Interface could get access to its target). This is moreover seamless for the user. TransitionAs a transitory method, in case the loader isn't patched yet (or if the StaticMethodLoader is used and the target is not provided). The Validator could fallback to the FlexibilityOn the other hand, I can see two slight reductions of flexibility in my approach compared to yours: BehaviourFirst, the behaviour, which could be one of
Separation between Validated Entities and Target RepositorySecond, my solution doesn’t allow to apply the Constraint on Class A, while targeting instances of Class B (which would be somewhere else in the hierarchy). This covers both an explicit I see three possibilities for this combinaison:
IMO, these are not deep issues, If you feel like a long(er) read, here is a detailed analysis of each case, otherwise, you might want to skip the next couple of paragraphs... In the first case (B is outside the inheritance line of A), it would mean that Students cannot have names used by Teachers, but the other way around wouldn’t be an issue. Additional care is required to ensure Students already existing do not conflict with a new Teacher name. This is a blacklisting semantic. While useful, we could argue this semantic isn’t covered by In the second case (B is a child class of A), it would mean that Persons cannot have names already used by Students, but names used by Teachers would be OK. This is very similar to the previous case and seems to carry the same Blacklisting semantic. Therefore, it falls outside of In the third and last case (B is a child class of A), it would mean that Teachers can have duplicated names, but Students can’t have duplicated names, nor the same name as Teachers. Although the first part of Students’ restrictions seems to be matching the Multiple Table inheritanceIn the case of Multiple Table inheritance, there are a few cases where the current implementation may not crash, since the UNIQUE Index may prove impossible to generate (if the field is represented differently in some subclasses). This would be another very similar bug. One might argue this to be a border-line use. If what we need is a per-table UniqueEntity behavior (similar to what separate UNIQUE Indices on separate tables would enforce), this should be enforced by using separate If what we need is an actual cross-table ConclusionWhat do you think? I know it's a bit of a complex implementation, but the code should be relatively simple and modular. I'm sorry to hijack your PR, but granted we both aim to solve the same issue I thought it would be a better idea to run it by you first. Again, if you think it should be in its own issue, don’t hesitate to tell me so and I’ll extract it from here. There is also the issue of which solution would be prefered by symfony/deciders. Thanks for taking the time to read all that if you did. It’s rather long and a bit tedious if I may say so myself. Anyway, all feedback will be welcomed and I hope both our solutions could be seen as complementary. |
@lemoinem Hey ! Very nice and well-written comment to expose your idea.
Don't worry. Please, submit a PR if you're confident enough. symfony/deciders will take a decision more easily and it'll give a new visibility to this issue. IMO, it's important, as it is kind of a "bug fix" but requires a feature implementation, and we're one month to the feature freeze. Also, as a side note to my own PR, I actually think the |
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
@ogizanagi Thank you very much for the feedback. I created a RFC (#16969) issue and two PRs (#16978,#16981) to provide a better understanding of my design. We'll just have to wait for @symfony/deciders to check on which is chosen ;) |
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
Fixessymfony#16969Fixessymfony#4087Fixessymfony#12573Incompatible withsymfony#15002Incompatible withsymfony#12977
What's the status of this PR? |
ogizanagi commentedJun 29, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
@fabpot :@lemoinem's work in#16978 and#16981 looks promising to me, but I'm not sure about the need to expose this new "target aware constraint" feature if the only use case mentioned until now is about solving the "UniqueEntityConstraint with inheritance" issue (#12573,#4087). On the other hand, I'm not satisfied by the new |
$supportedClass = $repository->getClassName(); | ||
if (!($entity instanceof $supportedClass)) { | ||
throw new ConstraintDefinitionException(sprintf('The "%1$s" entity repository does not support the "%2$s" entity. The entity should be an instance of or extend "%1$s".', $constraint->repository, $class->getName())); |
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.
- sprintf('The "%1$s" entity repository does not support the "%2$s" entity. The entity should be an instance of or extend "%1$s".', $constraint->repository, $class->getName())+ sprintf('The "%s" entity repository does not support the "%s" entity. The entity should be an instance of or extend "%s".', $constraint->repository, $class->getName(), $supportedClass)
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.
indeed
@fabpot Did you (or anyone else from the core team), had time to take a look at theses PRs? It would help if we at least knew which direction is favored. Both implementations are pretty much in a final state (short of rebasing them), and if neither is deemed good enough, a middle ground will surely be reached as@ogizanagi and I have already been collaborating on this. The critical element we need right now would be feedback. Sorry for the direct ping, but the issue is quite problematic, once one hit it... |
Thanks for the ping. Sorry, but I'm no Doctrine expert, so someone else from @symfony/deciders should probably review this one and give you some feedback.@HeahDude might have some opinions as well. I would of course be more than happy to merge this whenever we think this is "good enough" as you wrote. |
👍 but@chalasr's comment should be taken into account. |
$repository = $em->getRepository($constraint->repository); | ||
$supportedClass = $repository->getClassName(); | ||
if (!($entity instanceof $supportedClass)) { |
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.
The parentheses can be removed here
@@ -26,6 +26,7 @@ class UniqueEntity extends Constraint | |||
public $message = 'This value is already used.'; | |||
public $service = 'doctrine.orm.validator.unique'; | |||
public $em = null; | |||
public $repository = null; |
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.
If I understand correctly, this is a class name of the entity related to the repository. So,repository
is misleading here.
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.
UniqueEntity constraints --> why not simply$class
(i.e. entity class)
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.
Indeed, as I said, I was not satisfied by the name of this option. If you think$class
is a better candidate, let's do it. 👍
I did not use this name at first because the idea is to select and fix the repository to use for theUniqueEntity
constraint, and I thought at the moment it could be misleading as well to have aclass
option when you already set this constraint on an entity (useRepositoryOf="Person"
was probably conveying this idea better, but is an hideous name 😅 ).
ogizanagi commentedOct 7, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Thank you guys for the feedbacks. I'll update this PR very soon. :) |
@xabbuh#15002 (comment) is part of the main reason I came up with my proposal. Having the Constraint extracting "itself" (implicitly) the repository to use seemed ... cleaner from a design standpoint. Regarding the other use cases for a ConstraintAware, I detailed a few examples in#16969, mostly the idea is to provide constraints validating an instance among the list of existing instances. Other self-referencing mechanisms, White/Blacklisting is the most obvious example. I am afraid I don't a concrete example on hands, and I understand the applications will be limited. If we could find a way to register implicitly the class the constraint has been declared on, without adding the complexities of my design. I'm sure it would make a great trade-off for this issue. With an explicit way to specify the repository, I'm afraid some might misuse the Constraint and bring around bigger issues regarding compatibility or clarity. At least, I would insist on adding a note in the documentation to that effect. |
ogizanagi commentedOct 7, 2016 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
So, I've rebased this branch on master and made the suggested fixes. I've also renamed the
Of course, the new option has to be documented at least onthe UniqueEntity constraint page. Do you have some suggestions about what the user should be warned ? |
|
…iqueEntity validatorThe new option expects an entity path, in order to select its repository.This allows to properly use the UniqueEntity constraint on hierarchical (inheritance) entities, using the root class repository in order to check the uniqueness, and not just the child repository.
@fabpot : I've submitted the PR on the documentation repository. I think this is ready. :) |
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.
Looks good to me 👍
Thank you@ogizanagi. |
…ed by the UniqueEntity validator (ogizanagi)This PR was merged into the 3.2-dev branch.Discussion----------[DoctrineBridge] Add a way to select the repository used by the UniqueEntity validator| Q | A| ------------- | ---| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets |#12573,#4087,#12977| License | MIT| Doc PR |symfony/symfony-docs#7057This is a cherry pick of#12977 on ~~2.8~~ 3.2 branch, as it is clearly a new feature, even if it was primary introduced in order to fix an inappropriate behavior that might be considered as a bug.Commits-------00d5459 [Doctrine] [Bridge] Add a way to select the repository used by the UniqueEntity validator
…(ogizanagi)This PR was merged into the master branch.Discussion----------[DoctrineBridge] Document the new `entityClass` optionWaiting forsymfony/symfony#15002 to be merged.Commits-------a9c2fc2 [DoctrineBridge] Document the new `entityClass` option
Uh oh!
There was an error while loading.Please reload this page.
This is a cherry pick of#12977 on
2.83.2 branch, as it is clearly a new feature, even if it was primary introduced in order to fix an inappropriate behavior that might be considered as a bug.