Hello everyone !
I am struggling with macros in order to dynamically create a SQL query to search for various topics in multiple languages. To provide some context, I have a full text search query and I would like to perform queries based on the languages selected on the search bar.
For example, If a user selects english and italian, the query should look like this :
      """
      SELECT topic_id, topic_title, topic_description
          FROM (SELECT topics.id as topic_id, topics.title as topic_title, topics.description as topic_description
             setweight(topics.title_tsvector, 'A') ||
             setweight(topics.description_tsvector, 'B') as document
        FROM topics) topics_search
        WHERE topics_search.document @@ websearch_to_tsquery(english::text::regconfig, 'query') OR
        topics_search.document @@ websearch_to_tsquery(italian::text::regconfig, 'query')
      """
I took inspiration from this article and implemented the following :
topics.exs
defmacro multilang_search_topics(languages) do
    quote bind_quoted: [languages: languages] do
      sql =
        Enum.map(
          languages,
          fn _lang ->
            "topics_search.document @@ websearch_to_tsquery(?::text::regconfig, ?)"
          end
        )
        |> Enum.join(" OR ")
      """
      SELECT topic_id, topic_title, topic_description
          FROM (SELECT topics.id as topic_id, topics.title as topic_title, topics.description as topic_description,
             setweight(topics.title_tsvector, 'A') ||
             setweight(topics.description_tsvector, 'B') as document
        FROM topics) topics_search
        WHERE #{sql}
      """
    end
  end
defmacro multilang_search_topics(languages, search_query) do
    languages = quote(do: unquote(languages))
    arguments =
      languages
      |> Enum.map(
           &[
             quote(do: unquote(&1)),
             quote(do: ^unquote(search_query)),
           ]
         )
      |> List.flatten()
      |> List.insert_at(0, multilang_search_topics(languages))
    quote do
      fragment(unquote_splicing(arguments))
    end
  end
  def search(query \\ Topic, search_query, languages) do
    from topic in query,
         join: search in multilang_search_topics(languages, search_query),
         on: search.topic_id == topic.id
  end
I got tricked into thinking my solution was working because I hardcoded the languages argument like so : join: search in multilang_search_topics(["english"], search_query)
However, when I switched it back the search method triggers the following error : ** (Protocol.UndefinedError) protocol Enumerable not implemented for {:languages, [line: 121], nil} of type Tuple 
Now, I get that macros are receiving representation of arguments. I was wondering if there is a way to handle list argument without triggering the error ?
Thanks in advance to whoever might read and help. 





















