I have been struggling with put_assoc for days. It’s taken me awhile to get my head rapped around how to do associations with many-to-many tables when the related join is already created.
I’m presenting a multi-list of “resource types” to the user. They select multiple types and I get back the IDs for the associated table. I just need to make the association between the newly created “resource” and these “resource_types”. That is the join table. But I can’t seem to make this connection with put_assoc. Here is what I’ve got:
PARAMS coming in from form:
PARAMS
%{
“title” => “blah”,
“description” => “blah blah”,
“resource_types” => [“1”, “2”],
}
Here is my RESOURCE changeset that is trying to set the put_assoc for the RESOURCE_TYPES (the many_to_many relationship is set in the schema):
def changeset(resource, attrs) do
resource
|> cast(attrs, [:title, :description])
|> put_assoc(:resource_types, [parse_params(attrs, “resource_types”)])
end
defp parse_params(attrs, assoc_type) do
assoc_list = get_in(attrs, [assoc_type])
formatted_list_map = Enum.map(assoc_list, fn x → {:id, String.to_integer(x)} end)
IO.puts "ASSOC LIST"
IO.inspect(formatted_list_map)
formatted_list_map
end
** So when I print out that ASSOC LIST after all of the formatting it looks like this:
[id: 1, id: 2]. I made sure that I’m returning that formatted_list, so it should be getting passed into put_assoc. **
But I print out the newly created Resource Changeset out and the resource_type IDs are missing!!! And I’m getting an error because they are missing.
CHANGESET:
ecto.Changeset<
action: nil,
changes: %{
description: “blah”,
resource_types: [
ecto.Changeset<
action: :insert,
changes: %{id: 2},
errors: ,
data: project.Resourcetypes.Resourcetype<>,
valid?: true
>
],
title: “blah”
},
errors: ,
data: project.Resources.Resource<>,
valid?: true
Why is put_assoc not taking that keyword list?