我有下面的Ecto模型。当我尝试渲染时出现错误。如何修改@derive以便预加载?或者我必须写出实施?推荐的解决方法是什么?
** (RuntimeError) cannot encode association :tilemap_layers from MyProject.Tilemap to JSON because the association was not loaded. Please make sure you have preloaded the association or remove it from the data to be encoded
模型在这里:
defmodule MyProject.Tilemap do
use MyProject.Web, :model
@derive {Poison.Encoder, only: [
:name,
:tile_width,
:tile_height,
:width,
:height,
:orientation,
:tilemap_layers,
:tilesets
]}
schema "tilemaps" do
field :name, :string
field :tile_width, :integer
field :tile_height, :integer
field :width, :integer
field :height, :integer
field :orientation, :string
has_many :tilemap_layers, MyProject.TilemapLayer
has_many :tilesets, MyProject.Tileset
timestamps
end
@required_fields ~w(tile_width tile_height width height)
@optional_fields ~w()
@doc """
Creates a changeset based on the `model` and `params`.
If no params are provided, an invalid changeset is returned
with no validation performed.
"""
def changeset(model, params \\ :empty) do
model
|> cast(params, @required_fields, @optional_fields)
end
end
答案 0 :(得分:4)
简短的回答是你不应该。预加载数据不是视图层的责任。
在获取资源时(通常是控制器或从控制器调用的函数),您应该执行预加载。
例如使用Ecto.Repo.preload/3:
def index(_conn, _params)
timemaps = Tilemap |> Repo.all() |> Repo.preload(:timemap_layers)
render("index.json", tilemaps: tilemaps)
end
您还可以使用Ecto.Query.preload/3
在查询中执行预加载query = from t in Tilemap,
preload: [:tilemap_layers]
Repo.all(query)