Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating json from elixir ecto associations

I would like to generate JSON from an ecto association in phoenix.

this is my association:

defmodule Blog.Post do
  use Ecto.Model

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

and:

defmodule Blog.Comment do
  use Ecto.Model

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

when I generate json without the association the result is this:

[%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)"}]

and the json looks like this

{"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!!!!"
    }
]}

but with the association the outcome is this

[%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)"}]

With the above output I can't create a proper json output. I would like for the json to look something like this

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

Any help would be appreciated.

like image 764
idobn Avatar asked Nov 06 '14 16:11

idobn


Video Answer


1 Answers

Ouch, there is no easy solution at this moment. I would try something like:

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

We are basically implementing encoder for tuples that receives the proxy above and encoding all items. We need to discuss better solutions for this.

like image 120
José Valim Avatar answered Oct 11 '22 06:10

José Valim