-
-
Notifications
You must be signed in to change notification settings - Fork 921
Fix #944 - allows to filter by relation by keeping EagerLoading enabled #950
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
Conversation
65686a3
to
f220063
Compare
Query is now better:
This will work with the PaginationExtension as it doesn't alter the results, and it is optimized. |
f220063
to
105b6b2
Compare
WDYT? I'll add unit tests but I want to know first if this solution is fine to you or if you want to try another approach :). @api-platform/core-team |
Looks better, indeed. @ymarillet can you try if this patch fix the problem? |
@@ -94,6 +94,7 @@ private function handleConfig(ContainerBuilder $container, array $config, array | |||
$container->setParameter('api_platform.eager_loading.enabled', $config['eager_loading']['enabled']); | |||
$container->setParameter('api_platform.eager_loading.max_joins', $config['eager_loading']['max_joins']); | |||
$container->setParameter('api_platform.eager_loading.force_eager', $config['eager_loading']['force_eager']); | |||
$container->setParameter('api_platform.eager_loading.filter_relations', $config['eager_loading']['filter_relations']); |
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.
@teohhanhui suggestions about that parameter name ? \o/
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.
fetch_partial?
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.
fetch_partial to true would mean we want to fetch a partial relation?
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.
Yes. So the default should be false.
Or perhaps partial_relations
, partial_collections
, partial_collection_fetch
?
@@ -49,6 +49,7 @@ public function getConfigTreeBuilder() | |||
->booleanNode('enabled')->defaultTrue()->info('To enable or disable eager loading')->end() | |||
->integerNode('max_joins')->defaultValue(30)->info('Max number of joined relations before EagerLoading throws a RuntimeException')->end() | |||
->booleanNode('force_eager')->defaultTrue()->info('Force join on every relation. If disabled, it will only join relations having the EAGER fetch mode.')->end() | |||
->booleanNode('filter_relations')->defaultFalse()->info('Allow to filter the relation collection when the filter is on a nested property. By default, it will retrieve the full relation of the filtered resource. If enabled, only relations matching the filter will be returned.')->end() |
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.
Remind me to rewrite this for you. 😄
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.
!RemindMe
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.
When filtering on a nested property through a to-many relation, do not fetch the other items in the collection. Warning: this breaks round trip, as you cannot PUT the returned collection back to the parent property.
p/s: @soyuka Does this only happen when filtering on a nested property? Or whenever the other side of the relation is fetch-joined?
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.
Also, we need to warn that this would apply to every level in a multi-level nested property.
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.
Only when filtering on a nested property because it only joins the result matching that filter.
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.
When filtering by e.g. products?brands=/brands/1
, doesn't it result in SQL something like:
SELECT ...
FROM products
INNER JOIN products_brands
ON products.id = products_brands.product_id
INNER JOIN brands
ON products_brands.brand_id = brands.id
WHERE brands.id = 1
and thus:
{
"@id": "/products/1",
"brands": [
"/brands/1"
]
}
even if product 1 has other brands?
This is not a nested property. So I think the problem manifests itself when filtering on any to-many relation.
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 really think we should not have this option, because it results in returning invalid data. ("Product 1 has 1 brand which is Brand 1.")
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.
Not sure I understood, what is the relation type on products_brands and brands?
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.
Many-to-many. products_brands is the join table.
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.
Yeah your right I think that this option is too much confusing, ManyToMany relations are working fine, I've added a test case anyway.
I'm removing the availability to filter on the relation. I think that the best to filter a relation would be to use subresource
+ filter.
Haha I will <3
…On Fri, 24 Feb 2017 at 18:08, Teoh Han Hui ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/Bridge/Symfony/Bundle/DependencyInjection/Configuration.php
<#950 (comment)>:
> @@ -49,6 +49,7 @@ public function getConfigTreeBuilder()
->booleanNode('enabled')->defaultTrue()->info('To enable or disable eager loading')->end()
->integerNode('max_joins')->defaultValue(30)->info('Max number of joined relations before EagerLoading throws a RuntimeException')->end()
->booleanNode('force_eager')->defaultTrue()->info('Force join on every relation. If disabled, it will only join relations having the EAGER fetch mode.')->end()
+ ->booleanNode('filter_relations')->defaultFalse()->info('Allow to filter the relation collection when the filter is on a nested property. By default, it will retrieve the full relation of the filtered resource. If enabled, only relations matching the filter will be returned.')->end()
Remind me to rewrite this for you. 😄
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#950 (review)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ABQr82anStSF9DznfHu8OFAzADViAO3cks5rfw6mgaJpZM4MDT7B>
.
|
105b6b2
to
f06a3a7
Compare
@teohhanhui I refactored the fix, it's much cleaner and simple now. It clones the query and uses a subquery with the where clause to find the root entity identifiers. Origin query:
Fixed query:
This will work with any relation (manytomany, manytoone etc.). I've removed the parameter to skip this extension. |
8cdbec9
to
36c1ad5
Compare
fb1d84d
to
d03d4fe
Compare
ping @api-platform/core-team I think that this (as it's a bug fix) should target 2.0. Lmk. |
Yes, this is a bug fix. |
d03d4fe
to
167e3be
Compare
167e3be
to
495ea9e
Compare
Thank you very much @soyuka |
Fix api-platform#944 - allows to filter by relation by keeping EagerLoading enabled
filter_relations parameter seem not documented, it's still exist ? |
Nope. |
is it possible then to filter relations without a custom filters? @soyuka |
/!\ This is probably the worse code I've ever produced here and I hope we can find how to improve it together.
To fix #944 I needed to alter the query generated by the filters and the eager loading extension. To do so, I've added a
FilterEagerLoadingExtension
that patches the Query generated by theFilterExtension
.It runs directly after the
FilterExtension
and transforms the query so that it ends up doing something like:TODO:
forceEager
is not setApologizes to Scrutinizer, that complexity index will be very high -_-.