Siyu DU
Siyu DU

Reputation: 33

Dynamically choose field to update in elixir ecto

Its seems that the update in query expression accepts only keyword list (escape/3 in Ecto.Query.Builder.Update). So How can I define a function to dynamically choose a column to update?

Something like this:

def increment_field(column_name, count) when is_atom(field) do
     from t in Example.Entity, where: field(t, ^column_name) >= 0, update: [inc: [{^column_name, 1}]]
end

I'v tried this but got malformed :inc in update [{^column_name, 1}], expected a keyword list

I also tried to use figment/2, and field/2, but with no luck.

Upvotes: 3

Views: 861

Answers (1)

Dogbert
Dogbert

Reputation: 222148

From the examples in Ecto.Query.Builder.Update.escape/3 it looks like you cannot use ^ with the key, but you can use it before the whole keyword list, which will work for your use case.

With a model Counter with an integer field counter:

iex(1)> from(c in Counter, select: c.counter) |> Repo.all
[16, 2, -93]
iex(2)> field = :counter
:counter
iex(3)> from(c in Counter, update: [inc: ^[{field, 1}]]) |> Repo.update_all([])
[debug] UPDATE "counters" SET "counter" = "counter" + ? [1] OK query=2.5ms
{3, nil}
iex(4)> from(c in Counter, select: c.counter) |> Repo.all
[17, 3, -92]

Upvotes: 2

Related Questions