Ecto:如何通过选择另一个连接列来预加载记录

时间:2018-02-01 07:07:57

标签: elixir phoenix-framework ecto

有没有办法通过选择其他已加入的列来预加载记录?

#list

以下伪代码表达了我的目标(但不起作用)。

# table structure
# User 1---* Post 1---* PostTag *---1 Tag

# extract definition of scheme
scheme "posts" do
 ...
 has_many :post_tags, PostTag
 has_many :tags, [:post_tags, :tag]
end

我期待这样的结果。

query = from post in Post,
  join: user in User, on post.user_id == user.id,
  select: %{
    id: post.id,
    title: post.title,
    user_name: user.name, # <= column at joined table
  },
  preload: [:tags]
Repo.all(query)
#=> ** (Ecto.QueryError) the binding used in `from` must be selected in `select` when using `preload` in query:`

1 个答案:

答案 0 :(得分:3)

正如错误消息所示,您需要在预加载时选择from中给出的绑定,否则Ecto无法放置预加载的标记。这是一个简单的答案:

query = from post in Post,
  join: user in User, on post.user_id == user.id,
  select: {post, user.name},
  preload: [:tags]

通过返回元组,您可以获得完整的帖子和侧面的user.name。另一种方法是将post和users作为完整结构返回:

query = from post in Post,
  join: user in User, on post.user_id == user.id,
  preload: [:tags, user: user]

或者如果您不想要所有字段:

query = from post in Post,
  join: user in User, on post.user_id == user.id,
  preload: [:tags, user: user],
  select: [:id, :title, :user_id, user: [:name]]