2015-11-25 12 views
9

Mam modelu ekto dla adresu z tego schematu (uproszczony):Jak dodać wymagane pole warunkowe?

defmodule Address do 
    use Ecto.Model 

    schema "addresses" do 
    field :zip, :string 
    field :country, :string 
    # snip 
    end 

    @countries_requiring_zip ~w(US) # snip 

    def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, ~w(country), ~w(zip)) 
    |> validate_zip 
    end 

    defp validate_zip(changeset) do 
    if get_field(changeset, :country) in @countries_requiring_zip do 
     # ???? 
    end 

    changeset 
    end 
end 

Chcę zaznaczyć zip wymagane zamiast opcjonalne, ale tylko wtedy, gdy kraj znajduje się na białej liście, ale nie mogę wymyślić czysty sposób napisania sprawdzania poprawności. Jak dodać to ograniczenie?

Odpowiedz

11

można po prostu zdefiniować wiele rzuca też:

def changeset(model, params \\ :empty) do 
    model 
    |> cast(params, ~w(country), ~w()) 
    |> cast_by_country(params) 
end 

defp cast_by_country(changeset, params) do 
    case get_field(changeset, :country) do 
    "US" -> cast(changeset, params, ~w(zip), ~w()) 
    _ -> cast(changeset, params, ~w(), ~w(zip)) 
    end 
end 

get_field/2 odczyta wartość od zmian i awaryjne do jednej struktury, jeśli nie jest jeden. Jest to największa korzyść z zestawów zmian: jest to po prostu struktura danych i można używać zwykłego kodu Elixir do przeprowadzania sprawdzeń warunkowych, sprawdzania poprawności i tak dalej. Prosto do pisania, czytania i testowania. :)

0

Nie ma wyraźnej funkcji wymagającej pola poza cast. Możesz użyć funkcji validate_length/3 i zastąpić opcję ": message".

validate_length(changeset, :zip, min: 1, message: "is required when country is US") 
Powiązane problemy