-
-
Notifications
You must be signed in to change notification settings - Fork 461
Add an Argument Resolver #1413
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
Add an Argument Resolver #1413
Conversation
feab3e4
to
cc32106
Compare
b9b1123
to
a63a8a0
Compare
{ | ||
if (! $options['mapping']) { | ||
$keys = $request->attributes->keys(); | ||
$options['mapping'] = $keys ? array_combine($keys, $keys) : []; |
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 default mapping that takes all request attributes to find the entity is something that I'd like to make configurable (through the config, not in each argument), as it is quite confusing. I had several bugs in my project where an optional argument was suddenly given a weird value instead of null
just because the controller action had another argument with a name matching the name of an association (and that this default mapping would silently use it to build a criteria)
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.
providing a semantic configuration that will change the default behavior is something that could/should be done in a dedicated PR IMHO.
Maybe related to #1413 (comment)
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 don't want to disable the whole argument resolver. I want a way to disable the "use any other request param as a lookup" behavior. In my project, I never found a case where I wanted it, and I got several bugs caused by it for optional parameters of controllers.
Cases that actually want to do a lookup by another argument than the current argument will often need to provide a mapping explicitly anyway, as they expect to use a given field, not "any field" either (maybe they are just lucky that the names of their other controller arguments don't match fields that exist in their entity today, and they won't add new fields or new arguments in the future that would break that lucky invariant)
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.
Making this configurable globally would means bundles won't be able to rely on one the the behaviors. My take on this would be to completely remove the feature as something that is to much magic for an argument resolver.
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.
well, I'm also fine with removing the magic mapping entirely too (the mapping
option should still exist for cases where it is configured explicitly, as it solves a use case)
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.
id
and the attribute with the same name than the argument will both use the method find
. here we are talking about the fallback that use attributes that match none of the 2 cases above.
Disabling this feature globally does not make sens. If the request does not contain id
nor an attribute with the same, then there will be nothing to match, entity could not be found, and user would have to provide a mapping on every attributes anyway.
Sorry, I disagree with you
/blogs/{slug}
or /product/{uuid}
just work, and is often used. No need for custom mapping in such cases.
At the opposite, I never had issue with route containing several attributes. maybe I'm lucky, or because routes with multiple arguments are rare enough to provide mapping or expr and are not ambiguous
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.
anyway, I added a configuration section and added an auto_mapping
flag that allows users to disable this behavior. This will enforce people to either use {id}
(or the same name as the argument) OR to explicitly provide a mapping
option (or id
or expr
).
a63a8a0
to
f5670e9
Compare
f5670e9
to
a3de5a3
Compare
Maybe the resolver and attribute should go to the Doctrine Bridge instead of each bundle? Based on sensiolabs/SensioFrameworkExtraBundle#744 it seems like this could work OK for more than just the ORM. |
What do you mean by "each bundle". the PR you are referring is about ParamConverter and not Argument Resolver. This PR is about making the glue between Symfony and the ORM. The bundle sounds an appropriate place for such code. Edit sorry for multiple close/open currently typing on phone |
Based on how that PR reads, it sounds like the original param converter code would work just fine for any object manager (be it the ORM or any of the ODM implementations). So instead of this bundle, the MongoDB bundle, and the PHPCR bundle needing to re-implement basically the same class, they could all use one common class from the Doctrine Bridge and the bundles would just be left to handle the configuration bits. |
I agree. I would rather this was in doctrine-bridge. |
as mentioned, class should be in bridge and bundle will only provide wiring |
This PR migrates the SensioFrameworkExtraBundle's Doctrine ParamsConverter to Argument Resolver.
Moving away from ParamConverter would fix symfony/symfony#40333
usage:
enabled the behavior
The default configuration works out of the box. The entity is fetch using
$repo->find()
using the route's attribute.Options can be configured with a new Attribute
note: the business logic and tests are copy/pasted from the original repo. Tell me if you think some options are not needed anymore.