У меня есть функция, которая присваивает пользователю несколько навыков. Навыки уже существуют и имеют отношения many_to_many
с пользователем.
# skills will look like [%{id: "1"}, %{id: "4"}, %{id: "5"}] etc.
def reset(user, skills) do
user
|> Repo.preload(:skills)
|> Ecto.Changeset.change()
|> Ecto.Changeset.put_assoc(:skills, [])
|> Repo.update()
ids = Enum.map(skills, &Map.get(&1, :id))
query = Repo.all(from(p in Skill, where: p.id in ^ids))
skills = Enum.each(query, &Skill.create(user, &1))
end
В настоящее время это работает, но кажется неэффективным:
- Возможно, мы удаляем навыки, которые будут добавлены снова
- Возможно, вам не нужно запускать
Repo.all
для получения навыков, можете просто присоединиться к ним по ID, если они существуют
- Может быть упакован в
Ecto.Multi
для эффективности базы данных
В дополнение к этому было бы неплохо вернуть созданные умения, а не только атом :ok
, который возвращает Enum.each
.
Каков наилучший способ рефакторинга кода?