在将数据插入数据库后,由于对两个虚拟字段(:password和:password_confirmation)进行必需的验证(在更新过程中不需要),我发现很难更新记录。我仅在创建用户时需要此字段。
我尝试删除对这些字段的验证,但是由于这个原因,我无法在创建用户时验证数据。
用户架构
defmodule TodoBackend.User.Model.User do
use Ecto.Schema
import Ecto.Changeset
import Argon2, only: [hash_pwd_salt: 1]
schema "users" do
field :email, :string
field :name, :string
field :phone, :string
field :password_hash, :string
# Virtual fields:
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
timestamps()
end
@doc false
def changeset(user, attrs) do
user
|> cast(attrs, [:email, :name, :phone, :password, :password_confirmation])
|> validate_required([:email, :name, :phone, :password, :password_confirmation])
|> validate_format(:email, ~r/@/) # Check that email is valid
|> validate_length(:password, min: 8) # Check that password length is >= 8
|> validate_confirmation(:password) # Check that password === password_confirmation
|> unique_constraint(:email)
|> put_password_hash
end
defp put_password_hash(changeset) do
case changeset do
%Ecto.Changeset{valid?: true, changes: %{password: pass}}
->
put_change(changeset, :password_hash, Argon2.hash_pwd_salt(pass))
_ ->
changeset
end
end
end
用于更新用户的用户控制器功能
def update(conn, %{"id" => id, "user" => user_params}) do
user = UserRepo.get_user!(id)
IO.inspect(user)
with {:ok, %User{} = user} <- UserRepo.update_user(user, user_params) do
render(conn, "show.json", user: user)
end
end
Ecto回购定义
def update_user(%User{} = user, attrs) do
user
|> User.changeset(attrs)
|> Repo.update()
end
实际结果:我收到此错误{“错误”:{“密码”:[“不能为空”],“密码确认”:[“不能为空”]}}
预期结果:我希望验证仍然存在,并且仅应更新指定的字段
答案 0 :(得分:0)
您可以具有多个变更集功能。
def changeset(user, attrs) do
user
|> cast(attrs, [:email, :name, :phone])
|> validate_required([:email, :name, :phone])
|> validate_format(:email, ~r/@/) # Check that email is valid
|> unique_constraint(:email)
end
def registration_changeset(struct, params) do
struct
|> changeset(params)
|> cast(attrs, [:password, :password_confirmation])
|> validate_required([:password, :password_confirmation])
|> validate_length(:password, min: 8)
|> validate_confirmation(:password)
|> put_password_hash()
end
请注意registration_changeset
如何引用changeset
。这只是您如何进行设置的一个示例。您可以根据需要拥有多个变更集。毕竟它们只是功能!