Fl4m3Ph03n1x
Changeset is not validating data
Background
I am trying to create a schema with some basic validations. However, when I spin up my app, it looks like the validations are not running.
Code
This is the schema for a reservation.
defmodule MyApp.Reserve do
@moduledoc """
Represents a reservation for a guest.
"""
use Ecto.Schema
import Ecto.Query
alias Ecto.Changeset
schema "reserves" do
field :guest_id, Ecto.UUID
field :reserved, :decimal
field :paid, :decimal
field :category, Ecto.Enum, values: [:new, :returning]
end
def changeset(reserve, params \\ %{}) do
reserve
|> Changeset.cast(params, [:guest_id, :reserved, :paid, :category])
|> Changeset.validate_required([:guest_id, :reserved, :paid, :category])
|> Changeset.validate_number(:reserved, greater_than_or_equal_to: 0)
|> Changeset.validate_number(:paid, greater_than_or_equal_to: 10)
|> Changeset.validate_inclusion(:category, ["new", "returning"])
end
end
Iex
alias MyApp.Repo
alias MyApp.Reserve
reserve = %Reserve{guest_id: "bcf6dba1-8542-462e-ac16-6cfbe7be4cf6", reserved: 0, paid: -10}
Reserve.changeset(reserve)
#Ecto.Changeset<action: nil, changes: %{}, errors: [], data: #MyApp.Reserve<>, valid?: true, ...>
Question
This should be valid?: false since paid is a negative number. What am I missing?
Marked As Solved
dimitarvp
To have Ecto.Changeset work as designed you should give it an empty %Reserve{} and then pass parameters in the form of a regular map that contain all the pieces of data you want validated. Or a mix.
Also Liked
LostKobrakai
That’s not the issue. Validations run at the time the validation function is called.
Validations generally only validate changes, not the existing data on the reserve struct – they’re expected to be valid as supplied. You’re calling the changeset/2 function with no changes. validate_required is the only exception to that for Ecto.Changeset supplied validations.
michallepicki
oh, right, I got confused because Phoenix is not showing errors when the action is not set
dimitarvp
Yeah. First parameter to cast is data you already trust.







