Link Ecto with Multiple Circuits

Let's say I have these schemes:

defmodule Sample.Post do use Ecto.Schema schema "post" do field :title has_many :comments, Sample.Comment end end defmodule Sample.User do use Ecto.Schema schema "user" do field :name has_many :comments, Sample.Comment end end defmodule Sample.Comment do use Ecto.Schema schema "comment" do field :text belongs_to :post, Sample.Post belongs_to :user, Sample.User end end 

My questions are: how can I use Ecto.build_assoc to save a comment?

 iex> post = Repo.get(Post, 13) %Post{id: 13, title: "Foo"} iex> comment = Ecto.build_assoc(post, :comments) %Comment{id: nil, post_id: 13, user_id: nil} 

So far so good, all I have to do is use the same function to set user_id in my Comment structure, but since the return value of build_assoc is Comment struct, I cannot use the same function

 iex> user = Repo.get(User, 1) %User{id: 1, name: "Bar"} iex> Ecto.build_assoc(user, :comment, comment) ** (UndefinedFunctionError) undefined function: Sample.Comment.delete/2 ... 

I have two options, but none of them look good:

First you need to set user_id manually!

 iex> comment = %{comment| user_id: user.id} %Comment{id: nil, post_id: 13, user_id: 1} 

The second is to convert the structure into a map and ... I don’t even want to go there

Any suggestion?

+7
elixir ecto associations
source share
2 answers

Why don't you want to convert the structure to a map? It is really easy.

build_assoc expects the attribute map to be the last. Inside, he is trying to remove the key :__meta__ . Structures have the ability to compile temporary guarantees that they will contain all defined fields, so you get:

 ** (UndefinedFunctionError) undefined function: Sample.Comment.delete/2 

But you can just write:

 comment = Ecto.build_assoc(user, :comment, Map.from_struct comment) 

and everything will work fine.

+8
source share

Just pass it along with build_assoc

 iex> comment = Ecto.build_assoc(post, :comments, user_id: 1) %Comment{id: nil, post_id: 13, user_id: 1} 

Read more about here for more details.

+3
source share

All Articles