2015-10-17 41 views
9

Sup,中毒編碼嵌套模型

我試圖編碼一些嵌套的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 

回答

7

您需要爲類別定義相同的編碼器等等。其實,還有一個更容易做到這一點,如果你使用的是最新的毒藥,你可以寫:

defmodule Hangman.MasterCat do 
    use Ecto.Model 

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

這樣,藥劑需要自動實現對您的協議照顧。只要你爲你所關心的類型派生編碼器,你應該是好的。對於複雜的情況,明確地執行協議,就像你做的那樣,是要走的路。

+0

我已經這樣做了。我的協議有問題,需要我預先加載,目前我可能不需要。例如,當我顯示主分類列表時,我不想展示他們的孩子。但是當我展示整個結構時(出於某種原因)我需要展示它們。 – Haito

+1

您可以隨時在編碼器中預載,Ecto不會預載兩次。但我建議您根據需要正確預加載,而不是在編碼器中進行預加載。 –

+1

是的,即時嘗試做什麼,但我可能再次寫錯了我的問題。每個型號可以有多個編碼器嗎?如果沒有我編碼時沒有預加載的值,我試圖避免錯誤。 – Haito