Elixir 在“中调用我自己的谓词”;其中;外胚层
我希望能够调用一个函数或我的谓词(在“where”中)。我正在尝试这个:Elixir 在“中调用我自己的谓词”;其中;外胚层,elixir,ecto,Elixir,Ecto,我希望能够调用一个函数或我的谓词(在“where”中)。我正在尝试这个: items = where(Item, [x], Item.my_predicate?(x)) # items = where(Item, [x], Item.my_predicate?(x) == true) 它抛出一个异常: `Item.my_predicate?(x)` is not a valid query expression 如何修复它?我认为这是不可能的 作为一种方法,您可以创建一个单独的策略模块,该
items = where(Item, [x], Item.my_predicate?(x))
# items = where(Item, [x], Item.my_predicate?(x) == true)
它抛出一个异常:
`Item.my_predicate?(x)` is not a valid query expression
如何修复它?我认为这是不可能的 作为一种方法,您可以创建一个单独的策略模块,该模块实现在记录上或作为查询的一部分处理它的功能:
defmodule CheapItemPolicy do
alias Ecto.Query
import Query, only: [where: 3]
def is_cheap?(%Item{price: price}) do
price in 100..200
end
def is_cheap?(%Query{} = query) do
query
|> where([q], q.price >= 100)
|> where([q], q.price <= 200)
end
end
defmodule-CheapItemPolicy-do
别名exto.Query
仅导入查询:[其中:3]
def是否便宜?(%Item{price:price})是否便宜
价格以100..200为单位
结束
def是否便宜?(%Query{}=Query)do
查询
|>式中([q],q.price>=100)
|>其中([q],q.price当然可以,但是不能使用函数
例如:
defmodule Foo do
defmacro concat_ws(joiner, columns) do
params_list = "?" |> List.duplicate(Enum.count(columns)) |> Enum.join(",")
quote do
fragment(unquote("concat_ws(?," <> params_list <>" )", joiner, unquote_splicing(columns))
end
end
end
items = where(Item, [x], Foo.concat_ws(" ", [x.a, x.b]) == "a b")
但宏结果仍然需要是有效的查询AST,所以没有什么花哨的东西可以到达那里。卢卡斯的答案就是您所需要的。EXTO查询是在编译时生成的,所以如果您想使用某些东西作为谓词,就需要宏
但我想建议您也可以编写您的查询。这应该会让您产生以下想法:
def my_predicate(query, value) do
from r in query, where: r.some_column == ^value
end
然后像这样使用它:
query = from r in MySchema, where: r.another_column == ^another_value
query |> my_predicate(some_value)
基本上,使用可组合函数逐点构建查询
另外,我总是使用“查询”表单进行外部查询。你也可以使用“管道”通过将查询管道化到函数中来形成和组合查询。这是不可能的。当您有这样一个查询时,它需要转换为您的数据库查询语言。如果您开始在其中编写任意代码,则ecto将无法进行转换。如果您向我们提供您要运行的谓词和使用的DB的示例。为什么使用宏?我如何使用我自己的不需要片段的谓词?@Bingi您仍然需要使用宏作为,其中
也是构建exto的宏。查询
结构和所需的AST。无法调用列数据上的函数,因为它需要使用exto来传输将该功能代码指定给DB查询。Ecto查询中的所有内容都需要预先计算并作为原始数据发送到DB,或者需要可翻译才能进行查询。您不需要使用片段
,但通常情况下,当您需要Ecto宏时会出现这种情况。不过,您可以在那里自由编写任何可以在查询中使用的代码,否则就不需要了不可能。我怎么能使用我自己的谓词,它不需要片段?@Bingi在这种情况下,这是不可能的,因为我上面给出的原因。告诉我我需要什么,没有你我不知道。对不起,我不明白你的意思。你需要一个更具体的例子吗?
query = from r in MySchema, where: r.another_column == ^another_value
query |> my_predicate(some_value)