Elixir Ecto:多个连接和可重用/可组合查询

时间:2015-10-16 12:10:50

标签: join orm dependencies elixir ecto

在Ecto中,你可以像这样制作可重用/可组合的查询:

>>> s = 1
>>> def f():
...     print s
>>> print f()
1

>>> s = 1
>>> def g():
...     print s
...     s = 2
>>> print g()
Traceback (most recent call last):

UnboundLocalError: local variable 's' referenced before assignment

查看更多示例on this blog post

但是,我在使用多个连接时遇到问题。

假设我们有一个如下所示的模式:

  • AModel属于BModel
  • BModel属于CModel
  • CModel属于DModel

本文中提出的解决方案并不适用于深度连接:

defmodule AModel
  #...

  def anonymous(q), do: q |> where([am], is_null(am.user_id))
end

查询函数将绑定表作为第一个(连接的第二个)参数。 它包含以前的连接,并且很难加入订单。

在我们的例子中,q = DModel |> join(:inner, [dm], cm in assoc(dm, :c_models)) |> join(:inner, [_, cm], bm in assoc(cm, :b_models)) |> join(:inner, [_, _, bm], am in assoc(bm, :a_models)) |> AModel.anonymous 函数以起始表为目标。 但是在查询示例中,AModel是第4个绑定...

摆脱这种顺序依赖的任何想法或技术?

编辑:

我从博客作者那里得到了答案。 他告诉我,没有本地的其他方式来处理绑定而不是表中的位置。 他还this article强调了这一事实。

但是为了上帝的缘故,如果订单只重要,为什么我不能在它上面创建一个将名称与绑定索引相关联的命名映射?

这要问太多了:p?

2 个答案:

答案 0 :(得分:1)

使用命名绑定

Ecto 3.0为此用例添加了named bindings

答案 1 :(得分:-1)

也许创建一些junction tables

编辑:我可以看到,也许我有点太简洁了。我的意思是说你可以在后端建立联结表然后查询它们。这样您就不必担心在Ecto代码中构建连接。我希望这会使我的答案更加清晰。