在凤凰应用中,当用户提交特定表单时,lat和lng是根据地址计算的。
如果没有进行任何更改,则lat和lng可以在changeset.data中;如果提交了更改,则可以在changeset.changes中。
我在转换集上执行lat和lng上的其他内容,但我需要知道坐标的位置。我想做的是:
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
当然这不起作用,因为它没有在模式不匹配时返回true
或false
。
** (MatchError) no match of right hand side value: %{lat: any_value}
我实际上做了很长时间没有好看,如果....声明来实现这个。
有没有更好的灵丹妙药这样做?
答案 0 :(得分:2)
你可以在这样的函数中使用模式匹配:
...
# 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
代码未经测试,可能包含类型,但我希望您能理解。
答案 1 :(得分:2)
您可以使用case
匹配lat
和lng
内的changes
或data
:
case changeset do
%{changes: %{lat: lat, lng: lng}} -> ...
%{data: %{lat: lat, lng: lng}} -> ...
_ -> ...
end
但是,有更好的方法:Ecto有一个get_field
函数,用于处理从changes
获取字段值,自动回退到data
。
lat = get_field(changeset, :lat)
lng = get_field(changeset, :lng)
if lat && lng do
...
else
...
end