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

标签 elixir

这是我的用户模型

  @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

这是来自 Controller 的代码

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

我试图理解为什么验证未通过,并得到 hashed_pa​​ssword: "can't be Blank"

%Ecto.Changeset{
  changes: %{
    email: "<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="93e6e0f6e1d3fef2faffbdf0fcfe" rel="noreferrer noopener nofollow">[email protected]</a>",
    hashed_password: "$2b$12$6m6nlvykDzvvqgJQswAcxuu96./P2q/ToRRK0mKC//ITp9H6eFeH6",
    name: "user"
  },
  errors: [hashed_password: "can't be blank"]
  ...
 }

我看到 hashed_pa​​ssword 已添加到 :changes 但这个错误从何而来?

最佳答案

您需要在 hashed_pa​​ssword/2 将字段插入变更集中之前存在 hashed_pa​​ssword 字段。 cast/4 返回一个新的变更集,其中包含 “不能为空” 错误,因为在调用它时,hashed_pa​​ssword 字段不在参数中。

您可能想要做的是将必填字段中的hashed_pa​​ssword字段替换为password字段。这样,您就需要 password 字段位于 Controller 传递的参数中。

您不需要输入 hashed_pa​​ssword 字段,因为您是手动将其放入变更集中,因此您确信它会在那里。

关于elixir - 在写入 Ecto 中的数据库之前更新用户提供的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29978540/

相关文章:

ubuntu - (File.Error) 无法读取文件 "": no such file or directory

json - Elixir - 从 2 个集合创建 JSON 对象

nested - Ecto - 更新嵌套(多态)关联

elixir - 你能在 Elixir 中创建条件插件吗?

mysql - 外生灵药 : Sum values in preloaded association

Elixir - 合并 2 个列表列表(如列)

api - 在 Phoenix 中使用参数发布(没有 Ecto)?

elixir - 如何在 Elixir 中对枚举字符列表中的单个字符进行操作?

database - Ecto delete many_to_many join 同时保持连接记录完整

elixir - 我们如何解决 Elixir 中的冲突行为警告