Все, что вам нужно, это перебирать поля, условно обновляя набор изменений:
def encrypt(changeset) do
Enum.reduce(~w[address dob email]a, changeset, fn field, changeset ->
if changeset.changes[field] do
{:ok, encrypted} =
EncryptedField.dump(changeset.changes[field], key_id)
put_change(changeset, field, encrypted)
else
changeset # unlike your implementation this works
end
end)
end
Другим способом было бы Enum.filter/2
полей в первую очередь:
def encrypt(changeset) do
~w[address dob email]a
|> Enum.filter(&changeset.changes[&1])
|> Enum.reduce(changeset, fn field, changeset ->
{:ok, encrypted} =
EncryptedField.dump(changeset.changes[field], key_id)
put_change(changeset, field, encrypted)
end)
end
Sidenote: в соответствии с руководящими указаниями основной команды, трубы должны использоваться, если в цепи много звеньев.
Ответ на второй ответ:
Идиоматический код с использованием with
будет:
def encrypt(changeset) do
~w[address dob email] |> Enum.reduce(changeset, fn field ->
with %{^field => value} <- changeset.changes,
{:ok, encrypted} <- EncryptedField.dump(value, key_id)
do
put_change(changeset, field, encrypted)
else
_ -> changeset
end
end)
end