我不确定这是可能的,但我喜欢Repo.get返回一个Struct的事实。
我尝试做类似的事情:
Repo.get(User, id, select: [:id, :name])
喜欢在:
Repo.one(from u in User, where: u.id == ^id, select: [u.id, u.name]
但是使用Repo.get,我无法从Ecto文档中了解它是否可能以及如何实现这一目标。
背景信息:我使用Guardian并且序列化程序执行以下操作:
def from_token("User:" <> id), do: {:ok, Repo.get(User, id,)}
所以当我调用current_resource(conn)
时,我得到一个方便的用户结构。但是此查询会返回我尝试过滤的数据库中用户的所有信息(例如,我不想在我的current_resource(conn)
中加密密码。
答案 0 :(得分:3)
正如@Dogbert在评论中提到的解决方案是:
import Ecto.Query
from(User) |> select([:id, :name]) |> Repo.get(id)
在监护人序列化器中:
import Ecto.Query
....
def from_token("User:" <> id), do: {:ok, from(User) |> select([:id, :name]) |> Repo.get(id)}
.....
来自Ecto.Repo文档:
get(queryable,id,opts) get(queryable :: Ecto.Queryable.t,id :: term,opts :: Keyword.t):: Ecto.Schema.t | 零| no_return
从数据存储中获取主键与给定id匹配的单个结构。
如果未找到结果,则返回nil。如果可查询中的结构没有或多个主键,则会引发参数错误。
提到get/3
等待的第一个参数是可查询的。这就是为什么我们可以使用from(User) |> select([:id, :name])
构造可查询对象,然后将其传递给Repo.get(id)
这将返回基于user
模型的结构。
正如phoenix-framework docs提到的那样:
每个模型都定义了模式的字段及其类型。 它们每个都在我们的模式中定义一个具有相同字段的结构。
因此,返回的结构将具有模型/模式中描述的所有字段,但是具有nil值,我们不会选择它们。