首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ecto.Changeset不验证

Ecto.Changeset不验证
EN

Stack Overflow用户
提问于 2017-10-14 16:12:28
回答 1查看 553关注 0票数 1

我正在使用Ecto进行实验,并且在验证changeset()函数中的数据方面存在问题。

Schema如下:

代码语言:javascript
复制
defmodule Barakuda.TestData do
  use Ecto.Schema

  schema "test_data" do
    field :username, :string
    field :age, :integer
  end

  def changeset(data, params \\ %{}) do
    data
    |> Ecto.Changeset.cast(params, [:username, :age])
    |> Ecto.Changeset.validate_required([:username, :age])
  end

end

现在让我们尝试使用无效的数据:

代码语言:javascript
复制
iex(125)> d1=%Barakuda.TestData{id: 1, username: "polo"}
%Barakuda.TestData{__meta__: #Ecto.Schema.Metadata<:built, "test_data">,
 age: nil, id: 1, username: "polo"}
iex(126)> Barakuda.TestData.changeset(d1).valid?        
false

这是可以的,因为age字段丢失了。如果我移除username,也会发生同样的情况。很好!

现在,我在changeset()的末尾添加了以下一行(是的,我重新编译了):

代码语言:javascript
复制
data
  |> Ecto.Changeset.cast(params, [:username, :age])
  |> Ecto.Changeset.validate_required([:username, :age])
  |> Ecto.Changeset.validate_number(:age, less_than: 20)

如果age严格小于20,e.i.:19,18,.否则就是假的。对吗?让我们试一试:

代码语言:javascript
复制
iex(19)> d1=%Barakuda.TestData{id: 1, username: "polo", age: 15}
%Barakuda.TestData{__meta__: #Ecto.Schema.Metadata<:built, "test_data">,
 age: 15, id: 1, username: "polo"}
iex(20)> Barakuda.TestData.changeset(d1).valid?                 
true

这也没问题。现在还没有

代码语言:javascript
复制
iex(130)> d1=%Barakuda.TestData{id: 1, username: "polo", age: 22}
%Barakuda.TestData{__meta__: #Ecto.Schema.Metadata<:built, "test_data">,
 age: 22, id: 1, username: "polo"}
iex(131)> Barakuda.TestData.changeset(d1).valid?                 
true

其他validate_*函数也是如此,例如(有或没有count: :codepoints):

代码语言:javascript
复制
Ecto.Changeset.validate_length(:username, min: 6, count: :codepoints)

那我做错什么了?

注:灵丹妙药1.5.1和Ecto v2.2.6 (2017-09-30)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-10-14 17:00:12

validate_length不检查现有字段,只检查“更改”字段。

validate_length(变更集,字段,选项) 验证更改是给定长度的字符串或列表。

来源

由于您使用结构中的所有字段和params参数中的任何字段调用params,所以没有一个字段被Ecto标记为“更改”,而validate_length什么也不做。正确的方法是将现有的结构(具有默认值/现有值)作为第一个参数传递,并传递所有需要作为第二个参数params验证的添加。下面的代码应该为您返回false

代码语言:javascript
复制
changeset = Barakuda.TestData.changeset(%Barakuda.TestData{}, %{id: 1, username: "polo", age: 22})
changeset.valid?
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46746630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档