jejuro
August 12, 2020, 9:33am
1
I have a struct which belongs to z . Let’s assume values are decimals.
s = %S{a: 1, b: 2}
I want to update s with a variable, k , of which value will be either :a or :b .
When k ’s value is determined, I wanna update s like this;
s = Map.update!(s, k, &Decimal.add(&1, 5))
So, s will be update to %S{a: 6, b: 2} or %S{a: 1, b: 7}.
But s belongs to z , so, everytime s is updated, it needs put_assoc z repeatedly.
z |> put_assoc(:s, s) |> update
How to update s alone?
Thank you all.
idi527
August 12, 2020, 10:19am
2
put_assoc
acts on changesets, not plain structs. So are you trying to update plain nested structs, or nested changesets? I think the solutions would be a bit different for these two cases.
2 Likes
Adzz
August 12, 2020, 10:43am
3
It’s tought to say, because when you mention put_assoc it sounds like you are talking about database structs, not just structs?
If you are updating database struct, then you can always just update the struct you need to update.
Why do you think you need to put_assoc s?
Repo.get(S, 1)
|> Ecto.Changeset.change(%{a: 6, b: 2})
|> Repo.update!
Would update the S record alone.
2 Likes
jejuro
August 12, 2020, 11:09am
4
The issue is how to get %{a: 6, b: 2} map. It can be either %{a: 1, b: 7} or %{a: 6, b: 2} depending on the k value. So, the problem is how to apply k value to %{a: 1, b 2} to yield either %{a: 1, b: 7} or %{a: 6, b: 2}. Any idea?
PS> k is either :a or :b.
jejuro
August 12, 2020, 11:10am
5
Would you see the comment below I just added?
Adzz
August 12, 2020, 1:15pm
6
It looks like you have it already, with the Map.update, the below does the same thing:
s = %S{a: 1, b: 2}
k = :a
%{ s | k => Decimal.add(Map.get(s, k), 5) }
# Another way:
s = %S{a: 1, b: 2}
k = :a
changes = %{ k => Decimal.add(Map.get(s, k), 5) }
Ecto.Changeset.change(s, changes)
The above should return: %S{a: 6, b: 2}
, but I think you already had that working. Is it something after that that you are stuck on?
1 Like
jejuro
August 12, 2020, 2:12pm
7
Exactly what I need.
Thank you, Adzz .