Error interpolating a variable as the first argument of an Ecto fragment

Fragments have to be compile-time strings, it is to prevent sql injection attacks.

Your example can easily be done as something like:



def search(query, search_term, locale) do
    language =
      case locale do
        "pt" ->
          "Portuguese"
        "es" ->
          "Spanish"
        _ ->
          "English"
      end
    (from u in query,
    where: fragment("(to_tsvector(?, unaccent(?)) || 
                      to_tsvector(coalesce(?, unaccent(?)))) @@ plainto_tsquery('#{language}', unaccent(?))", ^language, u.name, ^language, u.name_label, ^search_term),
    order_by: fragment("ts_rank((to_tsvector(?, ?) ||to_tsvector(coalesce(?, ?))), 
                      plainto_tsquery(?, ?)) DESC", &language, u.name, language, u.name_label, ^language, ^search_term))
    |> Repo.all()
  end

Or something like that. :slight_smile:

It is also convenient to hide them behind def/defmacro’s for ease of use too.

1 Like