Hello there!
I’m trying to merge struct into a map by a form using Phoenix, by I didn’t encounter a way to make this by a “shortcut”.
The module looks like this:
defmodule Foo do
defstruct foo: ""
end
In a Phoenix form I receive this as params on submit:
%{"foo" => "bar"} = params
The expected result is:
%Foo{foo: "bar"}
By Map.merge(%Foo{}, params)
the fields are “duplicated” and the output is:
%{
:__struct__ => Foo,
:foo => "",
"foo" => "bar"
}
By struct(%Foo{}, params)
the foo param is not changed:
%Foo{foo: ""}
The way I found to get the expected result is mapping key params to atom:
params = Map.new(fn {k, v} -> {k |> String.to_atom(), v} end)
Then both Map.merge/2
and struct/2
give me the expected result %Foo{foo: "bar"}
.
If I change my module to this:
defmodule Foo do
defstruct "foo": ""
end
Then I receive a warning:
found quoted keyword “foo” but the quotes are not required. Note that keywords are always atoms, even when quoted. Similar to atoms, keywords made exclusively of ASCII letters, numbers, and underscores do not require quotes
…and receive unexpected results from both functions.
So, what’s the reason for a key when is_bitstring not be converted to atom by default?
Or what I’m doing wrong?