Confussed with build_assoc vs put_assoc vs cast_assoc

Can someone clearly explain to me the differences between build_assoc, put_assoc, and cast_assoc.
Also what should I use when?

This is what I have understood so far…

  • We use build_assoc when we are creating a new record and we want to associate it with a parent record by setting a foreign key like…

Building a comment and setting its belongs_to association by setting the post foreign key as…

Repo.get(Post, 13)
|> build_assoc(post, :comments)

# %Comment{id: nil, post_id: 13}

We can do this manually by comment.post_id = 13

  • We use put_assoc and put_embeded(for embedded schemas) when we have an existing record and we want to update its associations
  • It is used usually when the data is internal to the application.

  • This will delete all its old associations

%Comment{body: "Example"}
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(:post, post)
|> Repo.insert!()
  • We use cast_assoc and cast_embeded(for embedded schemas) when we have an existing record and we want to update its associations
  • It is used usually when the data is external to the application (we receive it in our params)

  • The will delete all its old associations

  • For this to work the associated records must define a changeset/2 function in their respective schemas

  • Cast assoc will keep the previous associations and add to it (unlike put_assoc which deletes all previous associations), if an association contains an id that conflicts with an already existing association then cast_assoc will update the conflicting child association with the new incoming values.

  • Cast assoc is helpfull when raw data comes in from an external source like a CSV file, etc.

(Like for a post all its associated comments come in as params and we need to cast it and update into the database.)

Can someone help me out to clear my understanding, if something is wrong in the above things I have understood or if I am missing something important.

31 Likes

From my perspective you got everything correct. Good job!

13 Likes

Here is a very detailed post from @josevalim about this topic if you have additional doubts:

http://blog.plataformatec.com.br/2015/08/working-with-ecto-associations-and-embeds/

This post has been updated.

Best regards,

6 Likes