Reputation: 3430
In a phoenix app, when a user submit a specific form, lat and lng are calculated from address.
The lat and lng can be in changeset.data if no changes are made and in changeset.changes if changes are submit.
I perform other stuff on lat and lng on the changeset but I need to know where the coordinates are. What I'm trying to do is:
cond do
# Always use new coordinates if possible
%{lat: lat, lng: lng} = changeset.changes ->
do_something(lat, lng)
%{lat: lat, lng: lng} = changeset.data ->
do_something(lat, lng)
true ->
do_nothing_and_return_the_changeset_as_is
end
Of course this is not working because it's not returning true
or false
on pattern not matching.
** (MatchError) no match of right hand side value: %{lat: any_value}
I actually made a long not looking good if else if .... statement to achieved this.
Is there a better elixir way of doing this?
Upvotes: 4
Views: 2330
Reputation: 222148
You can use case
to match on the lat
and lng
inside changes
or data
:
case changeset do
%{changes: %{lat: lat, lng: lng}} -> ...
%{data: %{lat: lat, lng: lng}} -> ...
_ -> ...
end
But, there's a better way: Ecto has a get_field
function which handles getting the field value from changes
, automatically falling back to data
.
lat = get_field(changeset, :lat)
lng = get_field(changeset, :lng)
if lat && lng do
...
else
...
end
Upvotes: 2
Reputation: 7344
You could use pattern matching in functions like this:
...
# call do_something with the changeset
changset |> do_something()
#pattern match for lat,lng inside the changes
def do_something(%Ecto.Changeset{changes: {lat: lat, lng: lng}}) do
..
end
# pattern match for lat,lng inside data
def do_something(%Ecto_.Changeset{data: {lat: lat, lng: lng}}) do
..
end
# pattern match if no lat und lng are available !!! the order of the functions matters !!!
def do_something(%Ecto_Changeset{} = cs) do
cs
end
Code is untested and may include types but I hope you will get the idea.
Upvotes: 2