How to change `or` and `and` condition in dynamic method?

Hello,

Newbie alert :grinning:

My company tries to move LARAVEL + VUE to Phoenix. We try to build a dynamic query system for Ecto.

I use dynamic method (macro) for building filter system. The SQL condition (“and” or “or”) come from the JSON. I need to pass condition (string or atom or some type) to dynamic method because I don’t want to write some function twice.

  def build_query(dynamic, "or", _data_type, field, _id, ">", value) do
    dynamic([q], ^dynamic or field(q, ^field) > ^value)
  end

  def build_query(dynamic, "and", _data_type, field, _id, ">", value) do
    dynamic([q], ^dynamic and field(q, ^field) > ^value)
  end

What I want,

  def build_query(dynamic, condition, _data_type, field, _id, ">", value) do
    dynamic([q], ^dynamic ^condition field(q, ^field) > ^value)
  end

But I get invalid query expression error.

** (Ecto.Query.CompileError) `condition()` is not a valid query expression.

What is the best way to pass a variable to dynamic as and and or and change it?

Regards.

2 Likes

There is no good way to do that. What you already have is the way to go.

Edit:

dynamic(fragment("? ? ?", 1, literal(^"OR"), 2))

This would work, but generally you want to avoid raw SQL where possible.