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

New directive that mirrors functionality of whereHas for relations (not @whereHasConditions) #2502

Open
loganswartz opened this issue Jan 29, 2024 · 1 comment

Comments

@loganswartz
Copy link

loganswartz commented Jan 29, 2024

What problem does this feature proposal attempt to solve?

It'd be really useful to have a directive equivalent of whereHas, to limit the result set of a query based on some restrictions on a nested field. I have a schema set up something like this:

extend type Query {
    orders(filter: OrderFilter @spread): [Order!]! @all
    lineItems(filter: LineItemFilter @spread): [LineItem!]! @all
}

type LineItem {
    id: ID!
    order: Order!
    product_id: ID!
    material_id: ID!
    # ...other attributes and relations omitted for brevity
}

type Order {
    id: ID!
    lineItems(filter: LineItemFilter): [LineItem!]! @hasMany
}

input LineItemFilter {
    product_id: ID @eq
    material_id: ID @eq
    # ...other filters omitted for brevity
}

I have a report that is essentially "get all orders that have line items matching a certain filter". What I'd ideally like to be able to do is something like this:

query GetOrders(filter: LineItemFilter!) {
    orders(has: "lineItems") {
        id
        lineItems(filter: $filter) {
            id
        }
    }
}

And then on the server side, I'm imagining something like this:

extend type Query {
    orders(filter: OrderFilter @spread, has: String @has): [Order!]! @all
}

To be clear, this isn't a simple scope or @where on the relation. What I'm after is for the hypothetical @has directive to take all the filters applied to the relation has (in this example, lineItems), and modify the top-level query to add a whereHas with the same set of constraints on that relation:

$query->whereHas($value, function (Builder $query) use ($value) {
    $this->enhanceBuilderFromNested($value, $query);
}

That way, any orders that don't have any line items matching the filter would be omitted from the final result set, and all the orders returned would have at least 1 matching line item.

Which possible solutions should be considered?

I looked at @whereHasConditions, but it really only lets you filter based on concrete columns, not any arbitrary conditions created by other directives.

I've also considered inverting this query, AKA querying lineItems and just getting the order field off of that, but then to get a list of orders, I need to flatMap the orders out, and re-match-up the line items, and it's just a bit of a pain for something that feels like it should be doable in GQL.

@loganswartz loganswartz changed the title New directive for using nested field constraints to constrain root query New directive that mirrors functionality of whereHas for relations (not @whereHasConditions) Jan 30, 2024
@LastDragon-ru
Copy link
Contributor

get all orders that have line items matching a certain filter

Probably you can look on my @searchBy directive.

Select all orders which have lineItems with id = xxx

orders(where: { lineItems: { where: { id: { equal: "xxx" } } } }) {
  id
  lineItems { ... }
}

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

No branches or pull requests

2 participants