Phoenix:上下文中的模式匹配参数(原子和字符串)
问题描述:
我有以下函数定义,我试图找到一种方法来简化参数,使它们都是统一的。Phoenix:上下文中的模式匹配参数(原子和字符串)
def update_user(%User{} = user, %{password: _} = attrs) do
attrs = Map.put(attrs, :password_reset_token, nil)
update_user(user, attrs, &User.password_changeset/2)
end
def update_user(%User{} = user, %{password_reset_token: _} = attrs), do:
update_user(user, attrs, &User.password_reset_changeset/2)
def update_user(user, attrs), do:
update_user(user, attrs, &User.changeset/2)
def update_user(user, attrs, changeset) do
user
|> changeset.(attrs)
|> Repo.update()
end
程序员可以混乱,起来,我想,通过传递与字符串键地图(地说%{"password" => value}
),它会与update_user/2
匹配。所以也许我应该更新这些函数的参数?或者使用update_user(user, attrs)
上的警卫来配合w/%{"password" => value}
?
def authenticate_user(%{"email" => email, "access_token" => _}) do
case get_by(%{email: email}) do
%User{} = user ->
{:ok, user}
nil ->
{:error, :non_existent}
end
end
def authenticate_user(%{"email" => email, "password" => password}) do
with %User{} = user <- get_by(%{email: email}),
{:ok} <- verify_password(password, user.password_hash),
do: {:ok, user}
end
那些PARAMS与一个地图,其具有字符串键匹配:
对比度与下文中,这需要直接从一个控制器功能(def create(conn, params)
)PARAMS。正如我所说,我这样做,因为那样我可以直接从控制器传递params
,并且模式匹配传入的内容(在这种情况下是各种登录方法)。是否有标准的凤凰方式来解决这类问题?
答
这里是一个可能的解决方案:
它可能不是最漂亮的解决方案,但我不认为两个字符串和原子键永远是匹配的。
def update_user(%User{} = user, attrs) do
user
|> user_changeset(attrs)
|> Repo.update()
end
def user_changeset(user, attrs) do
case attrs do
%{"password" => _} ->
User.password_changeset(user, Map.put(attrs, "password_reset_token", nil))
%{password: _} ->
User.password_changeset(user, Map.put(attrs, : password_reset_token, nil))
%{"password_reset_token" => _} ->
User.password_reset_changeset(user, attrs)
%{password_reset_token: _} ->
User.password_reset_changeset(user, attrs)
_ ->
User.changeset(user, attrs)
end
end
此外,您可以匹配模式函数的参数对于所有的情况,但我认为这是在这种情况下混乱。
另一种选择是首先总是将所有attrs
图转换为字符串键(相反,动态生成原子通常被认为是一个坏主意)。
一种方法是将所有原子键转换为字符串键,然后仅对字符串进行模式匹配。另一种方法是使用'cond',例如'cond do attrs [“password”] || attrs [:密码] - >#密码存在...'。我宁愿只用字符串键调用函数,因此只需要一个模式匹配(因为你不能改变具有字符串键的'params'的行为)。 – Dogbert