Ole*_*ann 11 elixir phoenix-framework
在这个小卫生功能的Phoenix/Elixir应用程序中,当用户没有输入电子邮件时,我会遇到问题.
我正在使用结构来处理数据.一个简单的卫生功能(现在)只是剥离空白并更新结构(地图).到目前为止,它的工作很好,但是当领域email是nil,我得到一个错误.
** (FunctionClauseError) no function clause matching in String.Unicode.strip/1
Run Code Online (Sandbox Code Playgroud)
所以我引入了一个guard子句来检查这种情况,然后只清理用户名.
defmodule MyApp.User do
defstruct username: nil, email: nil, password: nil, hashed_password: nil
# Sanitizing input without guard clause
def sanitize_user(user)do
%{user | username: String.strip(user.username), email: String.strip(user.email)}
end
# Sanitizing input with guard clause
def sanitize_user(user) when is_nil(user.email) do
%{user | username: String.strip(user.username)}
end
def sanitize_user(user) when is_binary(user.email) do
%{user | username: String.strip(user.username), email: String.strip(user.email)}
end
end
Run Code Online (Sandbox Code Playgroud)
现在我在编译时遇到错误:
** (CompileError) web/models/user.ex:54: cannot invoke remote function Access.get/2 inside guard
Run Code Online (Sandbox Code Playgroud)
我想是因为这个字段的值在编译时不可用.或类似的东西.
怎么解决这个?如何测试保护条款中结构的值?
Gaz*_*ler 23
您对编译时无法获得的值的假设是正确的.但是,您可以模式匹配地图中的值并在警卫中使用它们.
你可以编写你的函数:
def sanitize_user(%MyApp.User{email: nil} = user) do
%{user | username: String.strip(user.username)}
end
def sanitize_user(%MyApp.User{email: email} = user) when is_binary(email) do
%{user | username: String.strip(user.username), email: String.strip(user.email)}
end
Run Code Online (Sandbox Code Playgroud)
如果要允许传递其他结构(在这种情况下不太可能),也可以在没有User结构的地图上匹配:
def sanitize_user(%{email: nil} = user)
Run Code Online (Sandbox Code Playgroud)