2017-09-18 5 views
2

Je souhaite valider que ends_on est toujours postérieur ou égal à starts_on. Mais ma validation personnalisée ne fonctionne pas. Quelle est la bonne façon d'écrire cette validation?Valider qu'une date est postérieure ou identique à l'autre

defmodule Example.Calendar.VacationPeriod do 
    use Ecto.Schema 
    import Ecto.Changeset 
    alias Example.Calendar.VacationPeriod 

    schema "vacation_periods" do 
    field :ends_on, :date 
    field :name, :string 
    field :starts_on, :date 

    timestamps() 
    end 

    @doc false 
    def changeset(%VacationPeriod{} = vacation_period, attrs) do 
    vacation_period 
    |> cast(attrs, [:name, :starts_on, :ends_on]) 
    |> validate_required([:name, :starts_on, :ends_on]) 
    |> validate_dates_make_sense 
    end 

    defp validate_dates_make_sense(changeset) do 
    starts_on = get_field(changeset, :starts_on) 
    ends_on = get_field(changeset, :ends_on) 

    if starts_on > ends_on do 
     add_error(changeset, :starts_on, "cannot be later than 'ends_on'") 
    else 
     changeset 
    end 
    end 
end 

Répondre

3

Vous ne pouvez pas comparer les structures Date à l'aide des opérateurs de comparaison. Le module Date a une fonction compare/2 vous pouvez utiliser:

if Date.compare(starts_on, ends_on) == :gt do 
    add_error(changeset, :starts_on, "cannot be later than 'ends_on'") 
else 
    changeset 
end  

ou case:

case Date.compare(starts_on, ends_on) do 
    :gt -> add_error(changeset, :starts_on, "cannot be later than 'ends_on'") 
    _ -> changeset 
end