2016-05-30 47 views
1

我的代码:如何用Ecto创建一个可组合的?

defmodule Model1 do 
    use Ecto.Schema 
    import Ecto.Query 

    schema "model1" do 
    belongs_to :model2, Model2 
    end 

    def create_query do 
    Model1 
    |> join(:inner, [m1], m2 in assoc(m1, :model2)) 
    end 

    def apply_where(query, %{name: name}) do 
    query 
    |> where([m1, m2], ilike(m2.name, ^name)) 
    end 
end 


defmodule Model2 do 
    use Ecto.Schema 

    schema "model2" do 
    has_many :model1, Model1 
    field :name, :string 
    end 
end 

当我尝试:

param = %{name: "test"} 
Model1.create_query |> Model1.apply_where(param) |> Repo.all 

它的做工精细。但是,有没有什么办法可以这样编码apply_query函数:

def apply_where(query, %{name: name}) do 
    query 
    |> where([m2], ilike(m2.name, ^name)) 
end 

如果我的查询有很多连接子句?我是否必须在列表中声明所有连接的模式(表格)(首先在arg中)[m1,m2,m3,... mx]以每次绑定字段?

回答

0

因为m2是连接中的绑定,所以您必须指定[m1, m2]。这取决于位置,而不是名称,因此您的apply_where可以有[model_1, model_2],即使绑定使用不同的名称,ecto仍然会理解您的意思。

根据the docs

Bindings in Ecto are positional, and the names do not have to be consistent between 
input and refinement queries. 
... 
When composing queries you must specify bindings again for each refinement query. 

然而,在情况下,你有很多连接:

You are not required to specify all bindings when composing. 

而且在组成,你不担心的加入:

Although bindings are extremely useful when working with joins, they are not 
necessary when the query has only the from clause. 
+0

感谢您回答科迪投票! 在我的情况下,我使用查询两个片刻: 1 - 使用特定过滤器搜索数据(where子句) 2 - 搜索数据以使用不同的列填充三个组合框过滤器,并且在where子句中没有过滤器。我正在尝试使用相同的查询:对于组合框,我使用Ecto.Query.exclude函数删除select,order-by和preload。 如果连接被编辑,我对所有“apply_where”函数都有影响。可组合的查询没有用处,因为绑定是位置的,并且在处于不同范围(分离函数)时从不命名。 –