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

ilike operator in a string array inside a compound field #534

Open
ppff opened this issue Jan 17, 2025 · 0 comments
Open

ilike operator in a string array inside a compound field #534

ppff opened this issue Jan 17, 2025 · 0 comments

Comments

@ppff
Copy link

ppff commented Jan 17, 2025

Alternate title: custom field inside compound field.

Hello,

Let's say you have this schema:

schema "persons" do
    field :surname, :string
    field :names, {:array, :string}

Users need to be able to find someone by their first name, second name, or surname, from a single filtering text input using ILIKE.
So you need to derive the schema like this:

@derive {
    Flop.Schema,
    filterable: [:info],
    adapter_opts: [
      compound_fields: [
        info: [:surname, :names]
      ],
    ]
  }

And add a filter field like this:

info: [
      label: "",
      op: :ilike_and,
      type: "text",
      grow: "true",
      placeholder: gettext("Type something to filter entries...")
    ]

However, any filter request will crash because Flop will apply ILIKE to the names field which is an array, and postgres will say character varying[] ~~* unknown.

So, let's just use postgres function array_to_string to flatten the array before applying the ILIKE operator. First, let's create a custom field

custom_fields: [
  names_string: [
    filter: {App.FlopHelpers, :names_filter, []},
    ecto_type: :string,
    operators: [:=~, :like, :not_like, :like_and, :like_or, :ilike, :ilike_and, :ilike_or]
  ]
]

and a filter (which I restricted to ilike for simplification):

def names_filter(query, %Flop.Filter{value: value, op: _op}, _opts) do
    search = "%#{value}%"

    query
    |> where([p], ilike(fragment("array_to_string(?, ',')", p.names), ^search))
  end

And it works!

Now let's add the custom field to the compound field so we can search through all the fields at once!
And that's where elixir compiler ruins your joy with the following message from Flop library:

Compound fields must reference existing fields, but :info
references:

    [:names_string]

So:

  1. is this a bug that should be corrected to become a new feature? (being able to use custom fields in compound fields)
  2. does one have a better idea on how to do this without using a custom field?

My next idea is to store the string array as a string of comma-separated values, but I'd like to have your opinions first.

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant