elixir – 预加载关联和分页

我在PersonController中有一个show动作,它是这样的:

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)

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]>

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

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

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

最佳答案 Repo.preload期望接收模型或模型列表.看起来你正在传递一个查询.有两种解决方案:

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

点赞