`insert` 中的 password_hash 与类型不匹配:字符串

password_hash in `insert` does not match type :string

在我的用户上下文中,我定义了一个字符串类型的 password_hash 字段:

defmodule Catsdogs.UserContext.User do
use Ecto.Schema
import Ecto.Changeset

@acceptable_roles ["Admin", "Manager", "User"]

schema "users" do
  field :username, :string
  field :password, :string, virtual: true
  field :password_hash, :string
  field :role, :string, default: "User"
end

def get_acceptable_roles, do: @acceptable_roles

@doc false
def changeset(user, attrs) do
  user
   |> cast(attrs, [:username, :password, :role])
   |> validate_required([:username, :password, :role])
   |> validate_inclusion(:role, @acceptable_roles)
   |> put_password_hash()
end

defp put_password_hash(%Ecto.Changeset{valid?: true, changes: %{password: password}} = changeset) do
  change(changeset, password_hash: Pbkdf2.add_hash(password))
end

defp put_password_hash(changeset), do: changeset

end

在我的 seeds.exs 中,我创建了一个虚拟用户

{:ok, _cs} =
Catsdogs.UserContext.create_user(%{
  "password" => "t",
  "role" => "Manager",
  "username" => "manager"
})

为什么在添加用户时拒绝我的密码哈希字段,说它不匹配类型 :string,而实际上它确实匹配?

(Ecto.ChangeError) value `%{password_hash: "$pbkdf2-sha5120000$XfB4A.b62vcGfH2PpmDw8A$E9MNNWHftlgSJnYSwoc1cbUrsDQy24c.MbRdOLdeDBzwnWEOuFzVZuZW8noci3.H/WWUOuF34AQy9ndYIA/gIA"}` for `Catsdogs.UserContext.User.password_hash` in `insert` does not match type :string

虽然错误消息很清楚:%{password_hash: "$pbkdf2-sha5120000$XfB4A.b62vcGfH2PpmDw8A$E9MNNWHftlgSJnYSwoc1cbUrsDQy24c.MbRdOLdeDBzwnWEOuFzVZuZW8noci3.H/WWUOuF34AQy9ndYIA/gIA"} 不匹配字符串。那是因为它是一张地图。

您在使用 here:

中的代码时似乎犯了一个小错误
defp put_pass_hash(%Ecto.Changeset{valid?: true, changes:
    %{password: password}} = changeset) do
  change(changeset, Pbkdf2.add_hash(password)) # <-- CHANGE THIS LINE
end

defp put_pass_hash(changeset), do: changeset