Nested Associations in Phoenix 1.3 using cast_assoc

I’m trying to get nested associations to work in 1.3 using cast_assoc like this article does Nested Associations & Changeset Errors in Ecto. However I’m stuck. In 1.2, using cast_assoc was pretty simple. Since each schema was its own module you could do it this way:

# Model A
def changeset(struct, params \\ %{}) do
   struct
   |> cast(params, @required_fields)
   |> validate_required(@required_fields)
   |> cast_assoc(:bs, required: true)
end

You could basically do this indefinitely with each model defining its changeset to cast it’s associations changeset. I can’t figure out how to do this with contexts in 1.3.

Any assistance would be greatly appreciated.

3 Likes

You need to explicitly pass the changeset function for the associated schema:

|> cast_assoc(:bs, required: true, with: &bs_changeset/2)
5 Likes

That worked! Thanks so much!

1 Like

Ok. So that works for creating the changeset. However, while trying to use traverse_errors, it’s only providing errors for the A schema, not the B.

This is the code I’m using to get the errors.

Ecto.Changeset.traverse_errors(changeset, fn
  {msg, opts} -> String.replace(msg, "%{count}", to_string(opts[:count]))
  msg -> msg
end)

Am I doing something wrong here?

(Edit)

I just wanted to note that A has many B’s if that wasn’t clear.

2 Likes