2015-10-17 11 views
9

Sup,Poison Encode kodlama için iç içe modeller

Bazı iç içe Ekto Modellerini kodlamaya çalışıyorum ancak bir sorunla karşılaştım. Yüklenmemiş modeli kodlayamadığımı fark ettim ve yükleme istirahati olmadan sadece bir yapı seçebilme ve aynı zamanda tüm ağacı seçme olanağına sahip olmak istiyorum.

Ben defimpl ile yöntem, örnek kullandık:

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 

Bütün bu yapı için çalışıyor ama sadece MasterCats seçilmesi için çalışmaz ve böyle hata veriyor.

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 

cevap

7

Aynı kodlayıcıyı kategoriler için de tanımlamanız gerekir. Aslında, son Zehir kullanıyorsanız daha kolay bir bunu yapmak, yazabilirsiniz vardır:

defmodule Hangman.MasterCat do 
    use Ecto.Model 

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

Bu şekilde, Elixir sizin için otomatik protokol uygulanması ilgilenir. Enkoderi bakımını yaptığınız türden elde ettiğiniz sürece, iyi olmalısınız. Karmaşık durumlar için, protokolü sizin yaptığınız gibi, açıkça uygulamak, gitmek için bir yoldur.

+0

Ben zaten yaptın. Ihtiyaç duymayabileceğimi önceden yüklememi gerektiren protokolle ilgili bir sorunum var. Örneğin, ana kategorilerin listesini gösterdiğimde, çocuklarını göstermek istemiyorum. Ama bütün yapıyı gösterdiğimde (sebeplerden dolayı) onlara göstermem gerekiyor. – Haito

+1

Kodlayıcıda her zaman ön yükleyebilirsiniz, Ecto iki kez önyükleme yapmayacaktır. Ancak, kodlayıcıda yapmak yerine gerektiği kadar ön yüklemenizi tavsiye ederim. –

+1

Evet, yapmaya çalıştığım şey, ama yine de sorumu yanlış yazmış olabilirim. Model başına birden fazla kodlayıcı alabilir miyim? Önlemek istemediğim, önceden yüklenmiş değerleri kodlamada hata almazsam. – Haito