How to write this dynamic query?

hi.

I have a user table that has these fields and I want to list this user with 2 filters, One on the basis of name and the other on the role.

 schema "users" do
    field(:name, :string)
    field(:role, :string)
    field(:description, :string)

    timestamps()
  end

So I’m trying the example here which is mentioned in the documents

 def filter(params) do
    User
    |> where(^filter_where(params))
  end

  def filter_where(params) do
    Enum.reduce(params, dynamic(true), fn
      {"name", value}, dynamic ->
        dynamic([p], ^dynamic and p.name == ^value)

      {"role", value}, dynamic ->
        dynamic([p], ^dynamic and p.type == ^value)

      {_, _}, dynamic ->
        # Not a where parameter
        dynamic
    end)
  end

So I’m getting this error after this

(CompileError) cannot use ^filter_where(params) outside of match clauses

and second is this a way to achieve this?

Shouldn’t this be just |> where(filter_where(params)) ?

dynamic(true) does work.

I figured it out. But I’m still confused about how to achieve this problem. Can you guide?

For this case you don’t really need to use dynamic. Ecto queries are composable:

def filter(params) do
  # User is a query too
  Enum.reduce(params, User, &filter/2)
end

defp filter({"name", value}, query) do
  query |> where(name: value)
end

# ...
2 Likes