2017-10-14 52 views
0

我正在尝试使用Ecto,并且在验证changeset()函数中的数据时遇到了问题。Ecto.Changeset not validating

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是真实的,EI:19, 18,...否则返回false。对?让我们试试看:

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和外生V2.2.6(2017年9月30日)

回答

1

validate_length不检查现有油田中,只有 “变” 领域。

validate_length(变更,字段,选择采用)

验证的变化是给定长度的串或列表。

Source

既然你打电话Barakuda.TestData.changeset与在params论点的结构并没有什么所有的领域,如由外生“改变”和validate_length什么也不做任何字段被标记。这样做的正确方法是将现有结构(使用默认/现有值)作为第一个参数,并将所有需要验证的添加作为第二个参数params。以下代码应为您返回false

changeset = Barakuda.TestData.changeset(%Barakuda.TestData{}, %{id: 1, username: "polo", age: 22}) 
changeset.valid?