在 Ecto 中写入数据库之前更新用户提供的参数

Updating user supplied params before writing to db in Ecto

这是我的用户模型

  @required_fields ~w(name email hashed_password)
  @optional_fields ~w()

  def changeset(model, params \ nil) do
    model
    |> cast(params, @required_fields, @optional_fields)
    |> validate_length(:password, min: 6)
    |> hash_password(params["password"])
  end

  def hash_password(changeset, password) do
    put_change(changeset, :hashed_password, Bcrypt.hashpwsalt(password))
  end

这是来自控制器的代码

changeset = User.changeset(%User{}, user_params)

我试图了解为什么验证未通过,但我得到 hashed_password: "can't be blank"

%Ecto.Changeset{
  changes: %{
    email: "user@mail.com",
    hashed_password: "bm6nlvykDzvvqgJQswAcxuu96./P2q/ToRRK0mKC//ITp9H6eFeH6",
    name: "user"
  },
  errors: [hashed_password: "can't be blank"]
  ...
 }

我看到 hashed_password 已添加到 :changes,但此错误从何而来?

您需要 hashed_password 字段存在 ,然后 该字段被 hash_password/2 插入到变更集中。 cast/4 returns 一个带有 "can't be blank" 错误的新变更集,因为在调用它时,参数中的 hashed_password 字段 不是 .

您可能想要做的是用 password 字段替换 required 字段中的 hashed_password 字段。这样,你要求 password 字段在控制器传递的参数中。

您不需要要求 hashed_password 字段,因为您是手动将它放入变更集中,所以您确定它会在那里。