Update assocs having multiple primary keys when updating parent model without deleting unaffected records

Hello,

I have an issue with updating ecto relations. This is my parent schema:

@primary_key {:folder_id, :integer, []}
schema "folders" do
    field(:parent_id, :integer, default: nil)
    field(:folder_type, :string, default: "standard")
    
    timestamps(type: :naive_datetime_usec)

    has_many(
        :names,
        MyApp.Models.FolderName,
        foreign_key: :folder_id,
       on_replace: :delete
    )
end

And my child schema:
@primary_key false
schema “folder_names” do
field(:folder_id, :integer, primary_key: true)
field(:language, :string, default: nil, primary_key: true)
field(:name, :string)
end

And finally my def changeset for Folders
def changeset(folder, params) do
fields = ~w(parent_id folder_type)a

    folder
    |> Ecto.Changeset.cast(params, fields)
    |> Ecto.Changeset.cast_assoc(:names, on_replace: :update)
end

My application has an update route for folders which should also include the names. So the content is something like

%{
    folder_type: "standard",
    parent_id: nil,
    names: [%{
        %{language: "en", name: "rootfolder", folder_id: 42},
        %{language: "de", name: "Hauptordner", folder_id: 42}
    }]
}

Now I want to add another name as an update action:
%{
names: [%{language: “no”, name: “Høvedperm”, folder_id: 42}]
}

When now calling Repo.update with a corresponding changeset my other language names are deleted. Same applies when updateing some of the languages. I assume my problem is that I have two columns defining the primary key for names. Any ideas how to resolve this?

1 Like