预加载所有关系

时间:2015-11-14 15:54:10

标签: elixir phoenix-framework ecto

我的ERM与此类似:

--------     --------     --------
|ModelA|-----|ModelB|-----|ModelC|
--------     --------     --------

我使用以下内容获得ModelA及其ModelB:

modela = Repo.get(ModelA,1)
modela = preload(modela, :modelb)

现在我可以使用ModelB访问modela.modelb了。但是我怎么能预载ModelC呢?当我打印我的modelA时,它说,没有加载modelc。

3 个答案:

答案 0 :(得分:10)

您可以将列表传递给Repo.preload以加载多个关联。您甚至可以传递关键字列表来预加载嵌套关联。 我还发现在查询本身加载我需要的所有内容很有用(下面的两个选项是等效的):

query = from m in ModelA, preload: [modelb: :modelc]
Repo.get(query, 1)

Repo.get(ModelA, 1) |> Repo.preload(modelb: :modelc)

您还可以使用{association_name, query}传递元组以进行高级预编码 - 在许多关联中特别有用,以指定排序。

您可以在Ecto.Query.preload/3 docs

中阅读有关预加载的更多文档

答案 1 :(得分:3)

无法发表评论,但您必须在ModelA中定义嵌套关系。见Ecto.Schema

has_one :model_c, through: [:model_b, :model_c]

答案 2 :(得分:2)

您可以使用一个管道Repo查询预加载模型B及其模型C关联,而不必在模型A的模型定义中包含模型A和模型C之间的关联:

function addDeleteIconToTabs() {    
    var $tabItems = $('ul.k-tabstrip-items > li.k-item');
    $tabItems.each(function (index, tabLI) {
        var strTabId = $(tabLI).attr('aria-controls');
        var $tabContainerDiv = $('#' + strTabId);
        var intWorkOrderId = $tabContainerDiv.find('input.wohid').val();
        var strButtonHtml = "<button onclick='return deleteWorkOrder(this," + intWorkOrderId + ")' class='delete k-button' title='Delete Work Order'></button>";
        $(tabLI).append(strButtonHtml);
    });
}