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

[5.x] Add support for whereHas() and whereRelation() to entry and user query builders #8476

Open
wants to merge 23 commits into
base: 5.x
Choose a base branch
from

Conversation

ryanmitchell
Copy link
Contributor

@ryanmitchell ryanmitchell commented Jul 21, 2023

This PR adds support for queries on 'relationship' fields in the format:

$entries = Entry::query()->whereHas('entries_field', function ($subquery) {
   $subquery->where('title', 'Post 2');
});

$entries = Entry::query()->whereHas('entries_field');

$entries = Entry::query()->whereRelation('entries_field', 'title', 'Post 2');

I've added support to both Entry and User query builders, but as it can be easily added to other query builders if required - each query builder just needs to provide the appropriate blueprints through the getBlueprintsForRelations method.

The logic going on behind the scenes is to loop over the blueprint(s) and get the first relationship field type that has the same handle as the relation name being asked for. We then use the appropriate Facade to do another query to match the ids we want, and then do a check on the relationship field for those ids, this is provided by a new relationshipQueryBuilder() method on the fieldtype (currently only applied to entries and user fields, this would need to be extended).

It doesn't currently support checking counts on where callbacks (ie in the format):

Entry::query()->whereHas('entries_field', function ($query) {
    $query->where('content', 'like', 'code%');
}, '>=', 10)

And an InvalidArgumentException is thrown if this is attempted.

Looking forward to hearing your thoughts on this.

@ryanmitchell ryanmitchell changed the title Add support for whereHas() and whereRelation() to entry and user query builders [4.x] Add support for whereHas() and whereRelation() to entry and user query builders Jul 21, 2023
@jasonvarga
Copy link
Member

Awesome 🎉

@saqueib
Copy link

saqueib commented Sep 4, 2023

@jasonvarga when are you guys planning to release, need this badly

@duncanmcclean
Copy link
Member

duncanmcclean commented Sep 4, 2023

The Statamic Team will review this when they can.

In the meantime, you can use a composer patch to bring this PR into your project.

@justkidding96
Copy link
Contributor

@jasonvarga Any update on this pull request. I'm missing this issue right now in two projects. @duncanmcclean I've tried your method but I can't get it to work. It is stuck applying the patch. Also tried the beta version of the package without success.

@robdekort
Copy link
Contributor

@justkidding96 if you remove the tests from the patch file it should install without issues.

@godismyjudge95
Copy link
Contributor

Is there a possibility that a collection tag parameter could be added for easy filtering (ie. without creating a scope)

@godismyjudge95
Copy link
Contributor

@jasonvarga Any update on this pull request. I'm missing this issue right now in two projects. @duncanmcclean I've tried your method but I can't get it to work. It is stuck applying the patch. Also tried the beta version of the package without success.

I had the same issue; setting preferred-install (under config in composer.json) to source fixed it for me.

@godismyjudge95
Copy link
Contributor

godismyjudge95 commented Oct 5, 2023

Apologies for the spam on this, I'm just really invested in this feature 😂

Would love to see Taxonomy/Terms included in this feature. Here's the relevant code:

    // src/Stache/Query/TermQueryBuilder.php

    protected function getBlueprintsForRelations()
    {
        $wheres = collect($this->wheres);

        $taxonomies = $wheres->where('column', 'taxonomy')
            ->flatMap(function ($where) {
                return $where['values'] ?? [$where['value']] ?? [];
            })
            ->unique();

        if (!$taxonomies->count()) {
            $taxonomies = Facades\Taxonomy::all();
        }

        return $taxonomies->flatMap(function ($taxonomy) {
            if (is_string($taxonomy)) {
                $taxonomy = Facades\Taxonomy::find($taxonomy);
            }

            return $taxonomy ? $taxonomy->termBlueprints() : false;
        })
            ->filter()
            ->unique();
    }

@ryanmitchell
Copy link
Contributor Author

@godismyjudge95 yes it needs extended to a number of other field types, one of which is Taxonomies. My intention had been for the initial approach to be approved and merged after which I would raise separate PRs for the other field types to gradually get to complete support.

@robdekort
Copy link
Contributor

I had the same issue; setting preferred-install (under config in composer.json) to source fixed it for me.

Oh my this is brilliant. I don't know if there's any security downsides to this. But using this we can easily patch in PR's with tests via a GH link without manually downloading the patch file and removing the tests. Thanks.

@robdekort
Copy link
Contributor

This PR works very well. Thanks @ryanmitchell.

Copy link
Contributor

@godismyjudge95 godismyjudge95 left a comment

Choose a reason for hiding this comment

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

Otherwise this is working great for me. Currently testing it on a complex project for a client.

src/Stache/Query/TermQueryBuilder.php Show resolved Hide resolved
src/Stache/Query/EntryQueryBuilder.php Outdated Show resolved Hide resolved
@godismyjudge95
Copy link
Contributor

Just wanted to follow up on this and say the taxonomy and collection changes are working great for me. I've run into no other issues.

@godismyjudge95
Copy link
Contributor

If possible could you update this PR to the latest version? We are using it via composer patches. Thanks! :)

@godismyjudge95
Copy link
Contributor

If you get a chance could you update this for the latest Statamic version? (for composer patches) Thanks :)

@ryanmitchell ryanmitchell changed the base branch from 4.x to 5.x May 10, 2024 10:09
@ryanmitchell ryanmitchell changed the title [4.x] Add support for whereHas() and whereRelation() to entry and user query builders [5.x] Add support for whereHas() and whereRelation() to entry and user query builders May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants