2015-10-17 28 views
9

Sup,Poison Mã hóa mã hóa các mô hình lồng nhau

Tôi đang cố mã hóa một số Mô hình Ecto lồng nhau nhưng tôi đã gặp sự cố. Tôi nhận ra rằng tôi không thể mã hóa mô hình không tải và tôi muốn có khả năng chỉ chọn một cấu trúc mà không cần tải phần còn lại và đồng thời có khả năng chọn toàn bộ cây.

Tôi đã sử dụng phương pháp với defimpl, ví dụ:

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 

này làm việc cho toàn bộ cấu trúc nhưng nó không hoạt động để lựa chọn chỉ MasterCats và nó mang lại báo lỗi như vậy.

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 

Trả lời

7

Bạn cần xác định cùng một bộ mã hóa cho các danh mục, v.v. Trong thực tế, có một cách dễ dàng hơn để làm điều này, nếu bạn đang sử dụng Poison mới nhất, bạn có thể viết:

defmodule Hangman.MasterCat do 
    use Ecto.Model 

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

Bằng cách này, Elixir tự động thực hiện giao thức cho bạn. Miễn là bạn lấy được bộ mã hóa cho các loại mà bạn quan tâm, bạn sẽ tốt. Đối với các trường hợp phức tạp, thực hiện rõ ràng giao thức, như bạn đã làm, là con đường để đi.

+0

Tôi đã làm điều đó. Tôi gặp vấn đề với giao thức yêu cầu tôi tải trước mà tôi có thể không cần vào lúc này. Ví dụ: khi tôi hiển thị danh sách các Danh mục chính, tôi không muốn hiển thị con cái của họ. Nhưng khi tôi hiển thị toàn bộ cấu trúc (vì lý do) tôi cần phải cho họ thấy. – Haito

+1

Bạn luôn có thể tải trước trong bộ mã hóa, Ecto sẽ không tải trước hai lần. Nhưng tôi khuyên bạn nên tải trước đúng khi cần thiết thay vì thực hiện nó trong bộ mã hóa. –

+1

Vâng, đó là những gì đang cố gắng làm, nhưng tôi có thể đã viết lại câu hỏi của tôi sai. Tôi có thể có nhiều bộ mã hóa cho mỗi mô hình không? Nếu tôi không gặp lỗi khi mã hóa các giá trị không được tải sẵn mà tôi đang cố gắng tránh. – Haito