Sup,
I'm trying to encode some nested Ecto Models but i have encountered a problem. I realised that i can't encode unloaded model and i want to have possibility of selecting only one structure without loading rest and at the same time having possibility of selecting whole tree.
I have used method with defimpl, example:
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
This works for whole structure but it doesn't work for selecting only MasterCats and it gives such error.
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
You need to define the same encoder for categories too and so on. In fact, there is an easier to do this, if you are using latest Poison, you can write:
defmodule Hangman.MasterCat do
use Ecto.Model
@derive {Poison.Encoder, only: [:id, :name, :categories]}
schema "..." do
This way, Elixir takes care of automatically implementing the protocol for you. As long as you derive the encoder for the types you care, you should be good. For complex cases, explicitly implementing the protocol, as you did, is the way to go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With