2014-11-06 4 views
7

Я хотел бы сгенерировать JSON из ассоциации ecto в phoenix.Создание json из ассоциаций elixir ecto

это моя ассоциация:

defmodule Blog.Post do 
    use Ecto.Model 

    schema "posts" do 
    field :title, :string 
    field :body, :string 
    has_many :comments, Blog.Comment 
    end 
end 

и:

defmodule Blog.Comment do 
    use Ecto.Model 

    schema "comments" do 
    field :content, :string 
    belongs_to :post, Blog.Post 
    end 
end 

когда я генерировать JSON без ассоциации результат заключается в следующем:

[%Blog.Post{body: "this is the very first post ever!", id: 1,title: "first post"}, 
%Blog.Post{body: "Hello nimrod!!!!", id: 12, title: "hi Nimrod"}, 
%Blog.Post{body: "editing the body!!!!", id: 6, title: "hello(edit)"}] 

и JSON выглядит следующим образом

{"posts": [ 
    { 
     "title": "first post", 
     "id": 1, 
     "body": "this is the very first post ever!" 
    }, 
    { 
     "title": "hi Nimrod", 
     "id": 12, 
     "body": "Hello nimrod!!!!" 
    }, 
    { 
     "title": "hello(edit)", 
     "id": 6, 
     "body": "editing the body!!!!" 
    } 
]} 

но с ассоциацией исход этого

[%Blog.Post{body: "this is the very first post ever!", 
comments: {Ecto.Associations.HasMany.Proxy, 
#Ecto.Associations.HasMany<[name: :comments, target: Blog.Post, 
associated: Blog.Comment, references: :id, foreign_key: :post_id]>}, id: 1, 
title: "first post"}, 
%Blog.Post{body: "Hello nimrod!!!!", 
comments: {Ecto.Associations.HasMany.Proxy, 
#Ecto.Associations.HasMany<[name: :comments, target: Blog.Post, 
associated: Blog.Comment, references: :id, foreign_key: :post_id]>}, id: 12, 
title: "hi Nimrod"}, 
%Blog.Post{body: "editing the body!!!!", 
comments: {Ecto.Associations.HasMany.Proxy, 
#Ecto.Associations.HasMany<[name: :comments, target: Blog.Post, 
associated: Blog.Comment, references: :id, foreign_key: :post_id]>}, id: 6, 
title: "hello(edit)"}] 

С выше выход я не могу создать правильный вывод JSon. Я хотел бы, чтобы json выглядел примерно так

{"posts": [ 
    { 
     "title": "the title", 
     "id": 1, 
     "body": "the body", 
     "comments": [{"content": "a comment"}, {"content": "another comment"}] 
    } 
    ... 
]} 

Любая помощь была бы оценена.

+0

Какую библиотеку вы используете для создания JSON? Добавьте примерный фрагмент. –

+0

Это библиотека феникса по умолчанию, Poison: 'Poison.encode! % {posts: Blog.Repo.all (Blog.Post)} ' – idobn

+0

Я предполагаю, что вы получили сообщение об ошибке, верно? Не могли бы вы отправить сообщение об ошибке здесь? –

ответ

6

В этот момент нет простого решения. Я хотел бы попробовать что-то вроде:

defimpl Poison.Encoder, for: Tuple do 
    def encode(proxy, options) do 
    Poison.Encoder.List.to_json(proxy.all, options) 
    end 
end 

Мы в основном реализации кодера для кортежей, который получает прокси выше и кодирование всех элементов. Нам нужно обсудить лучшие решения для этого.

+0

Я не уверен, что я точно понимаю, что вы делаете ... Не могли бы вы показать пример того, как вы это сделаете. – idobn

+1

Это взломать неспособность Ecto к ассоциациям рендеринга. Вы должны добавить это в один из файлов вашего проекта, и этого должно быть достаточно, если только я что-то не упускаю, но прокси в приведенном выше коде - это значение, возвращаемое 'post.comments'. Рациональное заключается в том, что ассоциативный прокси-сервер является кортежем, поэтому вы преподаете Poison, как передать их JSON. –

+0

Я попытался добавить это в свой проект и получил следующее предупреждение: 'warning: undefined protocol function encode/2 (для протокола Poison.Encoder)' и после того, как я попытался запустить «Poison.encode! Blog.Repo.all (Blog.Post) 'Я получил эту ошибку:' ** (UndefinedFunctionError) undefined function: Poison.Encoder.Tuple.encode/2 (блог) Poison.Encoder.Tuple.encode ({Ecto.Associations .HasMany.Proxy, # Ecto.Associations.HasMany <[name:: comments, target: Blog.Post, related: Blog.Comment, ссылки:: id, foreign_key:: post_id]>}, []) ' – idobn