9

苏,

我正在尝试对一些嵌套的 Ecto 模型进行编码,但遇到了问题。我意识到我无法对未加载的模型进行编码,并且我希望有可能只选择一个结构而不加载其余部分,同时有可能选择整棵树。

我使用了 defimpl 方法,例如:

defimpl Poison.Encoder, for: Hangman.MasterCat do
    def encode(page, _options) do
      %{
        id: page.id,
        name: page.name,
        categories: page.categories
      } |> Poison.Encoder.encode([])
    end
  end
defimpl Poison.Encoder, for: Hangman.Category do
    def encode(category, _options) do
      IO.inspect(category.words)
      %{
        id: category.id,
        name: category.name,
        words: category.words
      } |> Poison.Encoder.encode([])
    end
  end
defimpl Poison.Encoder, for: Hangman.Word do
    def encode(page, _options) do
      %{
        content: page.content
      } |> Poison.Encoder.encode([])
    end
  end

这适用于整个结构,但不适用于仅选择 MasterCats,并且会出现此类错误。

cannot encode association :categories from Hangman.MasterCat 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
4

1 回答 1

7

您还需要为类别定义相同的编码器,依此类推。其实有一个更简单的方法,如果你使用的是最新的 Poison,你可以这样写:

defmodule Hangman.MasterCat do
  use Ecto.Model

  @derive {Poison.Encoder, only: [:id, :name, :categories]}
  schema "..." do

这样,Elixir 会自动为您实现协议。只要您为您关心的类型派生编码器,您就应该很好。对于复杂的情况,像您所做的那样显式地实现协议是要走的路。

于 2015-10-20T10:38:02.603 回答