我正在使用Ecto进行实验,并且在验证changeset()函数中的数据方面存在问题。
Schema如下:
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现在让我们尝试使用无效的数据:
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()的末尾添加了以下一行(是的,我重新编译了):
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,.否则就是假的。对吗?让我们试一试:
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这也没问题。现在还没有
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):
Ecto.Changeset.validate_length(:username, min: 6, count: :codepoints)那我做错什么了?
注:灵丹妙药1.5.1和Ecto v2.2.6 (2017-09-30)
发布于 2017-10-14 17:00:12
validate_length不检查现有字段,只检查“更改”字段。
validate_length(变更集,字段,选项) 验证更改是给定长度的字符串或列表。
由于您使用结构中的所有字段和params参数中的任何字段调用params,所以没有一个字段被Ecto标记为“更改”,而validate_length什么也不做。正确的方法是将现有的结构(具有默认值/现有值)作为第一个参数传递,并传递所有需要作为第二个参数params验证的添加。下面的代码应该为您返回false:
changeset = Barakuda.TestData.changeset(%Barakuda.TestData{}, %{id: 1, username: "polo", age: 22})
changeset.valid?https://stackoverflow.com/questions/46746630
复制相似问题