Can you check if an Ecto query already contains a filter?

I am finding myself in a situation where I am double-applying a certain filter in an Ecto query due to the query in question being passed around between two functions – one is a base query for the entire schema of sorts, the other has to limit records further but the base query might have conditionally already applied the same filter.

Is there a [officially sanctioned] way to check if a query already contains a certain where clause and avoid applying it more than once?

Maybe something can be done with named bindings and/or parent_as? Or with dynamic? Maybe with exclude?

1 Like

To clarify further, this is trivially done by just introducing one more function to pipe through and it avoids adding the double filter if the condition on which the previous function adds it is satisfied (so both functions kind of do opposite of what the other does). It works fine. I am simply curious if Ecto allows us to check if we already have a certain filter inside the query struct.

1 Like

I don’t believe this exists, but I’m also having trouble imagining an API if it did. Queries compose, but there’s not really any notion of “this specific where clause” (except for maybe a dynamic). And even if there was, a later composition can change the meaning. For instance,

|> where(…)
|> or_where(…)

If you reapplied the first where clause, it would change the meaning of the query.

1 Like

Yep but the idea is to not reapply it so something like e.g. put_new_where or just new_where or where(..., only_if_new: true) working similarly to Map.put_new could be workable.

Not advocating for it, no, just curious. And I would immediately agree that one should rework their code so such dilemmas never occur in the first place. :smiley: