2017-01-01 6 views
0

Изучение Elixir/Ecto и попадание в блокировку, связанную с наборами изменений. Не уверен, что я делаю неправильно.Ecto Changeset, обязательные поля не проверяются при изменениях

У меня есть структура «доменной модели», которая имеет некоторые обязательные поля. Когда я делаю put_change, возвращаемый набор изменений все еще говорит о наличии ошибки в наборе изменений (поле отсутствует), даже несмотря на то, что оно находится прямо там в изменениях.

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> 

Вышеупомянутое следует ожидать. оба relevant_date и display_time отсутствуют, и поэтому ошибки должны быть там.

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> 

Это часть, которая не имеет для меня никакого смысла. relevant_dateпрямо там в поле изменений, и все же он все еще говорит мне, что relevant_date can't be blank.

Любая помощь будет оценена!

EDIT: Это Ecto 2.1.1.

ответ

2

put_change не выполняет проверку, вам необходимо передать обновленный набор изменений через validate_required, поэтому он попытается выполнить проверку в обновленном состоянии.

Надеюсь, что это немного прояснит проблему!

EDIT

Просто для уточнения:

# 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]) 
+0

Спасибо! Это отвечает на мой вопрос. Будет ли запущен 'validate_required' также запустить все остальные проверки на changeeset? Есть ли идиоматический способ «повторного запуска» валидации в changeeset после изменения данных? – Brandon

+0

Рад помочь! Что касается вашего вопроса, вы можете решить это, извлекая все правила проверки для разделения функции (например, 'validate'), которая будет принимать« changeet », который вы могли бы передать через все _validating functions_, если это имеет смысл. Самое замечательное в Elixir/Ecto - это то, что вы можете сочинять все, что вам нужно, с помощью простых функций. Воспользуйтесь этим! –