有没有办法在不明确使用preload的情况下预加载ecto关联:?
类似于架构中的选项?
schema "gadgets" do
field :foo,
has_many :bars, Myapp.Bar, preload: true
end
我正在做类似
的事情Repo.get(Gadget, id)
|> Repo.preload: [:bars]
编辑:我尝试这样做的原因是因为我想将相关模型预加载到已经预加载的相关模型,例如
preload: [:invoices preload: :items]
答案 0 :(得分:29)
您还可以在查询中预加载:
defmodule Gadget do
use Ecto.Model
# ...
def with_invoices(query) do
from q in query, preload: [invoices: :items]
end
end
然后:
Gadget
|> Gadget.with_invoices
|> Repo.get!(id)
答案 1 :(得分:-3)
我不确定这是最快的方法,但我最后使用after_load回调来做这个,就像这样:
defmodule Invoice do
use Ecto.Model
after_load :preload_items
def preload_items(invoice) do
invoice |> Repo.preload([:items])
end
end
现在,每次加载Invoice时,即使它被其他东西预加载,它也会预加载其关联的项目。
编辑 - 不要这样做
将预加载放入查询中。使用上面的代码检索1000张发票将导致1 + 1000次查询。查询中的preload添加0NE。 查询。 1 + 1< 1 + 1< 1000 + 1。
query = from c in Gadget,
#retrieve nested associations adds one query
preload: [invoices: :items]
select c
Repo.all(query)