2017-08-19 93 views
3

在凤凰应用中,当用户提交特定表单时,lat和lng从地址计算。cond和模式匹配映射

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 

当然这是行不通的,因为它不是模式返回truefalse不匹配。

** (MatchError) no match of right hand side value: %{lat: any_value}

我居然做了一个长不找好,如果其他人如果....语句来实现这一点。

是否有更好的灵丹妙药?

回答

2

您可以使用case相匹配,对latlngchangesdata

case changeset do 
    %{changes: %{lat: lat, lng: lng}} -> ... 
    %{data: %{lat: lat, lng: lng}} -> ... 
    _ -> ... 
end 

但是,有一个更好的办法:外生具有get_field功能,处理来自changes获取字段值,自动落回到data

lat = get_field(changeset, :lat) 
lng = get_field(changeset, :lng) 
if lat && lng do 
    ... 
else 
    ... 
end 
+0

伟大的我不知道'get_field',这似乎也是一个很酷的选择! –

+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 

代码是未经测试,可能包括的类型,但我希望你能明白我的意思。

+0

写完我的问题后,我发现这是我到目前为止还没有测试过的选项。我现在正在尝试,我回到你身边! –