woylie / flop

Filtering, ordering and pagination for Ecto
MIT License
636 stars 35 forks source link

Basic "or" ability for Filter. #449

Closed aglassman closed 7 months ago

aglassman commented 8 months ago

This is just a draft PR to share my implementation of supporting 'or' filters.
It works, but is far from done. There are most likely edge cases where this will not work, specifically it will not work when using custom field info.

Filter:

    flop_params = %{
      filters: [
        %{field: :active, op: :==, value: true},
        %{or: 1, field: :valid_start, op: :empty, value: true},
        %{or: 1, field: :valid_start, op: :<=, value: now},
        %{or: 2, field: :valid_end, op: :empty, value: true},
        %{or: 2, field: :valid_end, op: :>=, value: now}
      ]
    }

Will generage:

SELECT count(*) FROM "redemptions" AS r0 WHERE  (((r0."valid_start" IS NULL) = $2) OR (r0."valid_start" <= $3)) AND (((r0."valid_end" IS NULL) = $4) OR (r0."valid_end" >= $5)) AND (r0."active" = $6) [true, ~U[2023-04-28 16:04:00.549945Z], true, ~U[2023-04-28 16:04:00.549945Z], true]
woylie commented 7 months ago

Thanks for sharing your implementation! I feel like grouping or clauses with an additional attribute like this will lead to less-than-ideal ergonomics when it comes to HTML forms. Nesting filters like proposed elsewhere might allow us to leverage inputs_for for filter groups. But this is nice for future reference.

aglassman commented 7 months ago

Agreed, I don't think this is an ideal solution. If nested filters are available for any pre-release testing at some point in the future, let me know and I give them a try in my current project. I've been using custom filters which work great, but could swap them out for a new approach easily.