2013-02-07 48 views
2

我在我的web表單上使用約束,我注意到有幾個表單有類似的驗證,例如我有幾種類型的表單,包括開始日期和結束日期。在每種情況下,我想驗證開始日期是否在結束日期之前。這裏的案例類,我從我的表單創建:如何在多個表單上共享一個validation.Constraint?

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

和我的驗證(讓我們忽略了獲得()現在):

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 
    } 
    } 

現在,因爲我有很多的形式與一個開始日期和一個結束日期,我想重新寫我的驗證,以處理所有代表這些表單的案例類。我想知道的類型類模式是否可以幫助我:

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)) 

產量:

error: type mismatch; found : OrderSearchForm required: 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) 

這似乎是一次尷尬多個驗證在起作用)

謝謝!

回答

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

這是有趣的,謝謝!我正在尋找一種解決方案,不需要我的模型共享相同的字段名稱。例如,我有另一個表單需要類似的驗證,'case class ShippedOrder(orderDate:Option [Date],shippedDate:Option [Date])'類型類型模式允許我將這些字段映射到TwoDates的startDate和endDate字段上按類別分類。你能想到一個允許這個的解決方案嗎? – scalapeno

相關問題