Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 构建宏以生成访问json键的片段_Macros_Elixir_Ecto - Fatal编程技术网

Macros 构建宏以生成访问json键的片段

Macros 构建宏以生成访问json键的片段,macros,elixir,ecto,Macros,Elixir,Ecto,假设我有一个jsonb字段,我想根据它的一个字段排序,它也应该使用dynamic,因为在编译时无法告诉字段名。我目前拥有的是: def order_by_dynamic([sort_direction, %{binding_name: binding_name, json_field: json_key, field: field}]) do [{sort_direction |> String.to_atom(), dynamic([{^binding_name, c}], cr

假设我有一个jsonb字段,我想根据它的一个字段排序,它也应该使用dynamic,因为在编译时无法告诉字段名。我目前拥有的是:

def order_by_dynamic([sort_direction, %{binding_name: binding_name, json_field: json_key, field: field}]) do
    [{sort_direction |> String.to_atom(), dynamic([{^binding_name, c}], create_fragment([{c.details, ^field}, json_key]))}]
  end

defmacro create_fragment(fields) do
    require Ecto.Query

    query = "?->>?"
    quote do
      fragment(unquote(query), unquote_splicing(fields))
    end
  end
此代码的问题在于它无法编译:

** (Ecto.Query.CompileError) Tuples can only be used in comparisons with literal tuples of the same size
    expanding macro: Ecto.Query.dynamic/2
在将json字段名传递给片段之前,我还尝试将其插入字符串中,错误是:

** (Ecto.Query.CompileError) to prevent SQL injection attacks, fragment(...) does not allow strings to be interpolated as the first argument via the `^` operator, got: `"?->>#{json_key}"`
    expanding macro: Ecto.Query.dynamic/2

我是否遗漏了某些内容,或者当前片段宏无法实现这一点?

好的,我似乎理解了,您需要直接从绑定中提供第一个参数,以避免sql注入:

defmacro create_dynamic_fragment(binding_name, field, json_field) do
    require Ecto.Query

    quote do
      dynamic([{^unquote(binding_name), c}], fragment("?->>?", field(c, ^unquote(field)), ^unquote(json_field)))
    end
  end

在引用之前,您应该插入
“?->?”
的左侧参数。有点像这里:你能提供一个MCVE吗?