2015-11-17 35 views
2

我有下面的Ecto模型。當我嘗試渲染時出現錯誤。我如何修改@derive以便預加載?或者我必須寫出實施?推薦的處理方法是什麼?Poison.Encoder如何預加載關聯?

** (RuntimeError) cannot encode association :tilemap_layers from MyProject.Tilemap 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 

該模型是在這裏:

defmodule MyProject.Tilemap do 
    use MyProject.Web, :model 

    @derive {Poison.Encoder, only: [ 
    :name, 
    :tile_width, 
    :tile_height, 
    :width, 
    :height, 
    :orientation, 
    :tilemap_layers, 
    :tilesets 
    ]} 

    schema "tilemaps" do 

    field :name, :string 
    field :tile_width, :integer 
    field :tile_height, :integer 
    field :width, :integer 
    field :height, :integer 
    field :orientation, :string 

    has_many :tilemap_layers, MyProject.TilemapLayer 
    has_many :tilesets, MyProject.Tileset 

    timestamps 
    end 

    @required_fields ~w(tile_width tile_height width height) 
    @optional_fields ~w() 

    @doc """ 
    Creates a changeset based on the `model` and `params`. 

    If no params are provided, an invalid changeset is returned 
    with no validation performed. 
    """ 
    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, @required_fields, @optional_fields) 
    end 
end 

回答

3

簡短的回答是,你不應該。預加載數據不是視圖層的責任。

當你提取你的資源使用Ecto.Repo.preload/2您應該執行預緊

例如:

def index(conn, params) 
    timemaps = Tilemap |> Repo.all() |> Repo.preload(:timemap_layers) 
    render("index.json", tilemaps: tilemaps) 
end 

您也可以進行預加載(通常是控制器或從控制器調用的函數。)在Ecto.Query.preload/3查詢:

query = from t in Tilemap, 
    preload: [:tilemap_layers] 
Repo.all(query) 
+0

謝謝Gazler,是有道理的吧! –