Multiple cast_assoc/3 in one line?

I have a list of associations [:a, :b, :c]
I want to pass them to cast_assoc/3 in one line, I have the changeset function:

def changeset(item, attrs) do
  fields = [:a, :b, :c]
  item
  |> cast(attrs, [])
  |> cast_assoc(fields |> Enum.at(0))
  |> cast_assoc(fields |> Enum.at(1))
  |> cast_assoc(fields |> Enum.at(2))
end

I want to cast them in one line

What do you mean by “in one line”? Presumably not this (which the formatter will turn back into what you posted above):

def changeset(item, attrs) do
  fields = [:a, :b, :c]
  item
  |> cast(attrs, [])
  |> cast_assoc(fields |> Enum.at(0)) |> cast_assoc(fields |> Enum.at(1)) |> cast_assoc(fields |> Enum.at(2))
end

You could make a function that reduces over the list of fields:

def cast_all_the_things(data, fields) do
  Enum.reduce(fields, data, fn field, data ->
    cast_assoc(data, field)
  end)
end

and then use it like:

def changeset(item, attrs) do
  item
  |> cast(attrs, [])
  |> cast_all_the_things([:a, :b, :c])
end

but IMO all that’s doing is hiding the cast_assoc calls and making it hard to pass specific options to specific casts.

1 Like

yes that’s it, thanks