预加载关联和分页

Rya*_*igg 5 elixir phoenix-framework

我的show动作PersonController是这样的:

person = Repo.get_by(Person, nick: params["nick"])
page = Message
|> where([m], m.person_id == ^person.id)
|> where([m], m.hidden == false)
|> order_by([m], desc: m.created_at)
|> Repo.preload(:channel)
|> Repo.paginate(page: params["page"], page_size: 250)
Run Code Online (Sandbox Code Playgroud)

paginate方法来自Scrivener软件包。

随着那条Repo.preload线,我得到这个错误:

key :__meta__ not found in: #Ecto.Query<from m in Logs.Message, where: m.person_id == ^34424, where: m.hidden == false, order_by: [desc: m.created_at]>
Run Code Online (Sandbox Code Playgroud)

如果删除Repo.preload,则此代码可以正常工作。我需要预加载频道,因为在消息模板中,我会生成指向特定频道的链接:

<a href='/<%= @message.channel.name %>?date=<%= date %>#<%= @message.id %>'>
  [<%= @message.created_at |> Calendar.Strftime.strftime!("%H:%M:%S") %>]
</a>
Run Code Online (Sandbox Code Playgroud)

一个人在一天内可以向其发送消息的渠道可能会有所不同,因此我想预加载这些渠道。我怎样才能做到这一点?

mic*_*ala 3

Repo.preload期望收到一个模型或模型列表。看起来您正在向它传递一个查询。有两种解决方案:

  1. Repo.preload调用后移动Repo.paginate- 此时我们正在处理模型(我假设Repo.paginate执行查询,我并不直接熟悉它)
  2. 将调用从 更改为Repo.preload-Ecto.Query.preload后者转换查询并将有关预加载的信息直接插入到生成的查询中