Один и тот же класс случаев, другая проверка

Что я пытаюсь сделать в Scala 2.11 и akka, так это иметь один класс case, но две разные проверки в зависимости от того, какой маршрут используется.

Например, давайте рассмотрим класс случая ниже

case class User(_id: String, name: String, age: Int, address: String)

Теперь, когда маршрут /create выбран, мне не нужно _id, но мне нужны все остальные поля.

Но пока маршрут /update задействован, мне нужен _id и поля, которые нужно обновить (которые могут быть одним или всеми тремя)

Только объявление Option не служит цели, потому что тогда мой маршрут /create идет на бросок.

Даже расширение case-классов на самом деле не работает гладко (слишком много дублирования кода).

Я был бы рад, если бы что-то подобное было возможно

case class User(_id: String, name: String, age: Int, address: String)

case class SaveUser() extends User {
    require(name.nonEmpty)
    require(age.nonEmpty)
    require(address.nonEmpty)
}

case class UpdateUser() extends User {
    require(_id.nonEmpty)
}

Есть ли элегантное решение для этого? Или мне нужно создать два одинаковых класса case?


person debduttoc    schedule 03.09.2018    source источник
comment
Используйте scala-cats validation аппликативный стиль   -  person pamu    schedule 03.09.2018
comment
почему вы не можете использовать опцию [_id] для того же класса case? и вы получите id из маршрута обновления и не получите _id в маршруте создания? что не так с этим дизайном?   -  person Raman Mishra    schedule 03.09.2018


Ответы (1)


Мое предложение состояло бы в том, чтобы кодировать разные классы case для разных требований, но если вы настаиваете на том, что вы должны использовать общий код между этими двумя случаями, возможным решением будет параметризация класса case.

case class User[Id[_], Param[_]](_id: Id[String], name: Param[String], age: Param[Int], address: Param[String])

Затем вы определяете псевдоним для конструктора типа Identity и два варианта использования класса case.

type Identity[T] = T
type SaveUser = User[Option, Identity]
type UpdateUser = User[Identity, Option]
person emilianogc    schedule 03.09.2018
comment
Или композицию, а не изменение определений User из-за беспокойства о сохранении (не интересно для чтения конечным пользователем); например case class Persistent[T](id: ..., value: T) можно использовать как Persistent(anId, anUserOrElse) (как Persistent[User]), с общими кодеками для Persistent с использованием соответствующих кодеков T (для вложенного или плоского кодирования). - person cchantep; 03.09.2018
comment
Я понял, что вариант использования заключается в том, что атрибуты пользователя являются необязательными в случае обновления. - person emilianogc; 03.09.2018
comment
@emilianogc Пробовал. Он работал как положено, даже спрей-json его подхватил и смог работать. Но я планировал генерировать кодеки bson для этого автоматически, используя кодеки mongo db. Но это невозможно, так как mongo для scala не поддерживает такой высокий вывод. Пришлось вернуться к некоему уродливому решению. Но я приму это. Так как это делает именно то, что я просил. - person debduttoc; 11.09.2018