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

BUGFIX many many through not sorting by join table #8534

Merged

Conversation

micmania1
Copy link
Contributor

@micmania1 micmania1 commented Oct 29, 2018

Resolves #7981

Todo:

  • Write new tests to cover default sort on main dataobject as well as join table
  • Add docs on sorting many many lists

many_many joins work by doing a join with two separate queries.

eg.

SELECT ...
 FROM "Fluent_Locale" INNER JOIN (
     SELECT ...
     FROM "Fluent_FallbackLocale"
     WHERE ("Fluent_FallbackLocale"."ParentID" = ?)
     ORDER BY "Fluent_FallbackLocale"."Sort" ASC
 ) AS "Fluent_FallbackLocale" ON "Fluent_FallbackLocale"."LocaleID" = "Fluent_Locale"."ID"
 ORDER BY "Fluent_Locale"."Locale" ASC

As you can see, the inner query is sorting correctly on the join table (by Sort ASC). However, the main query has its own sort which overrides that when you get the final set of results.

This inner query is built by SilverStripe using the standard ORM functions and assumes the default sort of the join DataObject (FluentFallbackLocale in this case). Likewise for the main query.

With @robbieaverill's fix it will sort correctly in cases where no default sort is set on the main DataObject and default is set on the join table data object. However, if the default sort is set on the main Dataobject, the fix will essentially be bypassed since sort is already set which is what we're seeing with Fluent.

The fix i've added applies the sort order much earlier, when it first starts building the ORM query objects. It will check to see if there is config which defines a default sort on the join table (this should also work for standard many-many sort too) and applies that if so. If that has no value, it will fallback to whatever sort SilverStripe gives it (default sort on dataobject or natural database sort).

This happens early enough that ->sort() will function as normal if the user decides to sort by something else and early enough that updateManymanyComponents can be hooked into.

@micmania1 micmania1 force-pushed the bugfix/7981-many-many-through-sort branch from 7c21edc to b1f24be Compare October 29, 2018 00:18
@micmania1 micmania1 force-pushed the bugfix/7981-many-many-through-sort branch from b1f24be to 6223126 Compare October 29, 2018 00:20
@mfendeksilverstripe
Copy link
Contributor

I tested this solution with the Fluent module which uses MMTL for fallbacks. It works fine, however we will need to add private static $default_sort = '"Fluent_FallbackLocale"."Sort" ASC'; to the FallbackLocale to use this new solution.

@tractorcow
Copy link
Contributor

I had an idea once where you could declare the sort directly on the many_many array config, so you could override the model-specific sorts, but just for that relation.

e.g.

private static $many_many = [
    'Items' => [
        'through' => Relation::class,
        'from' => 'Parent',
        'to' => 'Child',
        'sort' => '"App_Relation"."Sort" ASC',
    ],
];

@mfendeksilverstripe
Copy link
Contributor

+1 for Damian's idea. However, at this point, we will be happy with whatever solution that works.

@micmania1 micmania1 added this to the Recipe 4.3.0 milestone Oct 30, 2018
Copy link
Member

@ScopeyNZ ScopeyNZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code LGTM. Tried it locally and it worked.

Thanks for the tests and doc updates 👍

@unclecheese unclecheese merged commit 7086f2e into silverstripe:4 Nov 1, 2018
@micmania1 micmania1 deleted the bugfix/7981-many-many-through-sort branch November 1, 2018 01:13
unclecheese pushed a commit that referenced this pull request Nov 1, 2018
* BUGFIX many many through not sorting by join table

* #8534 added docs to support many many sorting fix

* #8534 added test cases for many_many default sorting
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SS4: Cannot sort many_many result when using through
5 participants