I have this Ecto.Schema
with the changeset
like below:
def changeset(current_case, attrs) do
current_case
|> cast(attrs, [:case_id, :latitude, :longitude, :user_id])
|> cast_coordinates()
end
def cast_coordinates(changeset) do
lat = get_change(changeset, :latitude)
lng = get_change(changeset, :longitude)
geo = %Geo.Point{coordinates: {lng, lat}, srid: 4326}
changeset |> put_change(:coordinates, geo)
end
Basically, it is a simple table taking in case_id
, latitude
, longitude
, user_id
.
Occassionally, user will update their location but sometimes, they only update the case_id
without update location.
cast_coordinates
will take latitude
and longitude
to convert it into geo point
then input into changeset
.
when create/1
, I won't have issue, because changes
in changeset
will have all the data.
but when update/2
, I will get argument error
if I only want to update:
latitude
only, because longitude
in changes
will be nil
.longitude
only, because latitude
in changes
will be nil
.nil
.latitude
or longitude
from current_case
, changeset will treat them as no changes, thus the value will be nil
.How can I resolve this?
Use get_field/3 instead of get_change/3.
get_change/3
only fetches changes, so if attrs
doesn't include latitude or longitude, it will return nil
.
get_field/3
fetches from the changes or from the data. When updating, your data from current_case
should contain the current latitude and longitude values, which will be returned instead of nil
.