Как совместно использовать validation.Constraint в нескольких формах?

Я использую ограничения в своих веб-формах, и я заметил, что несколько форм имеют похожие проверки, например, у меня есть несколько типов форм с датой начала и датой окончания. В каждом случае я хочу убедиться, что дата начала предшествует дате окончания. Вот класс дела, который я создаю из своей формы:

   case class OrderSearchForm(orderId: Option[Int], startDate:Option[Long], endDate:Option[Long])

и моя проверка (давайте пока проигнорируем .get ()):

  def validateSearchDate = Constraint[OrderSearchForm]{ 
    osf: OrderSearchForm => {
      if (!osf.startDate.isEmpty && !osf.endDate.isEmpty && osf.startDate.get.compareTo(osf.endDate.get) > 0 )
        Invalid("Begin Date is after End Date.")
      else
        Valid
    }
  }

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

trait TwoDates[T] { 
  def twoDatesTuple(t: T): (Option[Long], Option[Long]) 
}

trait TwoDatesOSF extends TwoDates[OrderSearchForm] { 
  def twoDatesTuple(t: OrderSearchForm) = (t.startDate, t.endDate) 
}

implicit object TwoDatesOSF extends trait TwoDatesOSF

def validateSearchDate = Constraint[TwoDates[_]] { t: TwoDates[_] => ... (as above)}

но применение не работает:

validateSearchDate(OrderSearchForm(None, None, None))

дает:

ошибка: несоответствие типов; найдено: OrderSearchForm Требуется: TwoDates [_] betweenDates (osf)

1) Могу ли я написать общие проверки с использованием классов типов? Если да, то что я делаю не так?

2) Могу ли я написать общие проверки, ИЗБЕГАЯ использования суперклассов (т.е.

abstract class TwoDates(start: Option[Long], end:Option[Long])

case class OrderSearchForm(orderId: Option[String], startDate:Option[Long], endDate:Option[Long]) extends TwoDates(startDate, endDate) 

что кажется неудобным после нескольких проверок)

Спасибо!


person scalapeno    schedule 07.02.2013    source источник


Ответы (1)


Думаю, можно использовать структурные типы:

private type TwoDates = { def startDate: Option[Date]; def endDate: Option[Date] }

def validateTwoDates = Constraint[TwoDates] { osf: TwoDates =>
if (!osf.startDate.isEmpty && 
    !osf.endDate.isEmpty && 
    osf.startDate.get.compareTo(osf.endDate.get) > 0) {
        Invalid("Begin Date is after End Date.")
    } else Valid
}

case class Something(
   startDate: Option[Date], 
   endDate: Option[Date], 
   name: String)

private val form = Form(mapping(
   "startDate" -> optional(date),
   "endDate" -> optional(date),
   "name" -> text)
(Something.apply)(Something.unapply).verifying(validateTwoDates))
person maxmc    schedule 08.02.2013
comment
Это интересно, спасибо! Я ищу решение, которое не требует, чтобы мои модели использовали одни и те же имена полей. Например, у меня есть другая форма, требующая аналогичной проверки, case class ShippedOrder(orderDate: Option[Date], shippedDate: Option[Date]) Шаблон класса типов позволил бы мне сопоставить эти поля с полями startDate и endDate TwoDates для каждого класса. Вы можете придумать решение, позволяющее это сделать? - person scalapeno; 08.02.2013