Проверка присутствия в Elixir Ecto, но только при вставке или обновлении

Чтобы проверить наличие параметра, вы можете добавить поле в атрибут модуля required_fields в модели. Затем вы передаете это методу cast модели, который проверяет наличие поля.

Но что, если вы хотите только проверить наличие чего-либо при вставке или обновлении?

Например, я хочу проверить наличие пароля пользователя только в том случае, если запись не сохраняется. Другими словами, я не хочу, чтобы пользователь вводил пароль при редактировании информации своей учетной записи.

Лучшее, что я придумал, - это иметь два разных набора обязательных полей для обновления и вставки, а затем выбрать подходящий метод:

# in changeset method
cast(params, required_fields(model), @optional_fields)

defp required_fields(model) do
  if Map.has_key?(model, :id) do
    @update_required_fields
  else
    @insert_required_fields
  end
end

Это разумно, или есть лучший способ?

РЕДАКТИРОВАТЬ

Добавление предложений от @michalmuskala с добавлением дополнительного вопроса об общих функциях набора изменений:

def insert_changeset(model, params \\ :empty) do
  model
  |> cast(params, @insert_required_fields, @insert_optional_fields)
  |> shared_changeset
end

def update_changeset(model, params \\ :empty) do
  model
  |> cast(params, @update_required_fields, @update_optional_fields)
  |> shared_changeset
end

defp shared_changeset(changeset) do
  changeset
  |> validate_password
  |> unique_constraint(:email)
end

person Elliot Larson    schedule 30.11.2015    source источник


Ответы (1)


Самое простое решение — создать две функции набора изменений — одну для вставки и одну для обновления. Таким образом, вы получите что-то вроде:

def update_changeset(model, params \\ :empty) do
  model
  |> cast(params, @update_required_fields, @optional_fields)
end

def insert_changeset(model, params \\ :empty) do
  model
  |> cast(params, @insert_required_fields, @optional_fields)
end

А позже в контроллерах вместо вызова Model.changeset/2 вы будете вызывать Model.update_changeset/2 или Model.insert_changeset/2.

person michalmuskala    schedule 30.11.2015
comment
Похоже, вам понадобятся атрибуты модуля вставки и обновления как для обязательных, так и для необязательных полей. Я немного обновил содержание своего вопроса для последующего вопроса. Если бы вы использовали этот подход с использованием двух наборов изменений, и у вас было бы несколько преобразований, которые были разделены между вставкой и обновлением, вы бы затем создали закрытый метод shared_changeset, который вызывали бы методы вставки и обновления набора изменений? - person Elliot Larson; 01.12.2015