learning Elixir/Ecto, and have hit a snag related to changesets. Not sure what I'm doing wrong.
I have a "domain model" struct that has some required fields. When I do a put_change
, the returned changeset is still saying there's an error on the changeset (field missing), even though it is right there in the changes.
cset = Activity.changeset(%Activity{}, %{details: "Played in the snow", child_id: child_id})
#Ecto.Changeset<action: nil,
changes: %{child_id: "ed553c30-38d2-4cb1-9029-eb2180c141cc",
details: "Played in the snow"},
errors: [relevant_date: {"can't be blank", [validation: :required]},
display_time: {"can't be blank", [validation: :required]}],
data: #MyApp.Domain.Activity<>, valid?: false>
The above is to be expected. both relevant_date
and display_time
are missing, and as such the errors should be there.
cset |> Ecto.Changeset.put_change(:relevant_date, ~D[2016-12-31])
#Ecto.Changeset<action: nil,
changes: %{child_id: "ed553c30-38d2-4cb1-9029-eb2180c141cc",
details: "Played in the snow", relevant_date: ~D[2016-12-31]},
errors: [relevant_date: {"can't be blank", [validation: :required]},
display_time: {"can't be blank", [validation: :required]}],
data: #Kidgenius.Domain.Activity<>, valid?: false>
This is the part that doesn't make any sense to me. relevant_date
is right there on the changes field, and yet it's still telling me that relevant_date can't be blank
.
Any help would be appreciated!
EDIT: This is Ecto 2.1.1
.
put_change
doesn't perform validation, you need to pass updated changeset through validate_required
, so it will try to perform validation on your updated state.
Hope that clarifies the problem a bit!
EDIT
Just for clarification:
# 1.
cset =
Activity.changeset(
%Activity{},
%{details: "Played in the snow", child_id: child_id}
)
# 2.
cset = Ecto.Changeset.put_change(cset, :relevant_date, ~D[2016-12-31])
# 3. This probably is something you currently have implemented
# in your `Activity.changeset`, most likely as second setep
# after `Ecto.cast/3`.
cset = Ecto.Changeset.validate_required(cset, [:relevant_date])