我有一个使用hierarchy
键形成parent_id
的主题模型。我希望能够在不进行递归选择的情况下快速访问路径,因此在this guide之后使用Postgres ltrees会有额外的hierarchy
字段。
defmodule App.Topic do
use App.Web, :model
schema "topics" do
field :name, :string
field :hierarchy, :string
belongs_to :parent, App.Topic, foreign_key: :parent_id
end
end
ltree部分工作正常,在数据库中看起来像这样:1.2.5
其中每个数字都是祖先主题的id。
问题是如何加载主题,并预先加载其祖先主题?
一条有希望的路线似乎是preload functions,但我无法让它发挥作用。在控制器中我有:
query = from t in App.Topic,
where: fragment("hierarchy @> (SELECT hierarchy FROM topics WHERE id = ?)", ^id)
topic = Repo.get!(Topic, id)
|> Repo.preload([ancestors: ^query])
我添加has_many :ancestors, App.Topic, foreign_key: :parent_id
让Ecto抱怨外键但可能不正确。