In my user context I define a password_hash field of type string:
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
In my seeds.exs, I create a dummy user
{:ok, _cs} =
Catsdogs.UserContext.create_user(%{
"password" => "t",
"role" => "Manager",
"username" => "manager"
})
Why is it denying my password hash field when adding a user, saying that it does not match type :string, when surely it does?
(Ecto.ChangeError) value `%{password_hash: "$pbkdf2-sha512$160000$XfB4A.b62vcGfH2PpmDw8A$E9MNNWHftlgSJnYSwoc1cbUrsDQy24c.MbRdOLdeDBzwnWEOuFzVZuZW8noci3.H/WWUOuF34AQy9ndYIA/gIA"}` for `Catsdogs.UserContext.User.password_hash` in `insert` does not match type :string
The error message is quite clear though: %{password_hash: "$pbkdf2-sha512$160000$XfB4A.b62vcGfH2PpmDw8A$E9MNNWHftlgSJnYSwoc1cbUrsDQy24c.MbRdOLdeDBzwnWEOuFzVZuZW8noci3.H/WWUOuF34AQy9ndYIA/gIA"}
does not match a string. That's because it's a map.
It looks like you made a small error when using the code from 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