2015-10-17 21 views
9

Sup,Kodowanie zagnieżdżone Kodowanie zagnieżdżone modele

Próbuję zakodować niektóre zagnieżdżone modele Ecto, ale napotkałem problem. Zdałem sobie sprawę, że nie mogę kodować niezaładowanego modelu i chcę mieć możliwość wyboru tylko jednej struktury bez ładowania odpoczynku i jednocześnie mając możliwość wyboru całego drzewa.

Użyłem metoda z defimpl, przykład:

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 

To działa dla całej konstrukcji, ale to nie działa do wyboru tylko MasterCats i daje taki błąd.

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 

Odpowiedz

7

Musisz zdefiniować ten sam enkoder dla kategorii i tak dalej. W rzeczywistości nie jest łatwiej to zrobić, jeśli używasz najnowszej trucizna, można napisać:

defmodule Hangman.MasterCat do 
    use Ecto.Model 

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

ten sposób Elixir dba o automatyczne wdrożenie protokołu dla Ciebie. Dopóki otrzymujesz koder dla typów, które są ci potrzebne, powinieneś być dobry. W przypadku złożonych przypadków jawnie implementacja protokołu, tak jak Ty, jest drogą do zrobienia.

+0

Już to zrobiłem. Mam problem z protokołem wymagającym ode mnie wstępnego załadowania, którego może nie potrzebować w tej chwili. Na przykład, gdy wyświetlam listę kategorii głównych, nie chcę pokazywać ich dzieci. Ale kiedy pokazuję całą strukturę (z powodów), muszę je pokazać. – Haito

+1

Zawsze można wstępnie załadować w enkoderze, Ecto nie będzie wstępnego ładowania dwa razy. Ale zaleciłbym wstępne załadowanie w razie potrzeby, zamiast robić to w koderze. –

+1

Tak, to co chcę zrobić, ale mogę ponownie napisać moje pytanie źle. Czy mogę mieć więcej niż jeden koder na model? Jeśli nie mam błędu, gdy kodowanie nie jest wstępnie załadowane wartościami, których próbuję uniknąć. – Haito