具有Lift中的特征的通用字段验证

时间:2014-03-14 16:39:20

标签: validation scala lift traits lift-record

我尝试定义trait Required来封装逻辑以验证所需Record Field的存在,但是,我还没有能够弄清楚自我类型应该是什么。我的目标是能够尽可能地写出一些东西,例如object foo extends SomeField(...) with Required但是我确实意识到我可能必须明确地将一些类型参数传递给Required

到目前为止我的无能为力是:

import net.liftweb.record.Field import net.liftweb.util.FieldError

trait Required[ThisType, OwnerType] {
  this: Field[ThisType, OwnerType] =>
  def errMsg = "is required"

  override def validations = {
    val required =
      (x: String) => if (x.isEmpty) List(FieldError(this, errMsg)) else Nil
    // this asInstanceOf call also seems fishy
    // --why's it even required if we already have the self type in place?
    required :: super.asInstanceOf[Field[ThisType, OwnerType]].validations
  }
}

但是,这会导致与存在类型相关的编译错误和警告:

myfield = object SomeField(...) with Required[SomeField[SomeModel], SomeModel]

就简明with Required而言,更不用说了。

修改

我提出了这个问题:

trait Required[OwnerType] extends Field[String, OwnerType] {
  def errMsg = "is required"

  override def validations = {
    val required =
      (x: String) => if (x.isEmpty) List(FieldError(this, errMsg)) else Nil
    required :: super.validations
  }
}

但是,它不允许我将required添加到super.validations,因为它期望this.type.ValueType => List[FieldError]不是String => List[FieldError],我觉得这很奇怪,因为在Field[String, ...]ValueType String

如果我将required更改为ValueType => ...,则会进行编译,但会出现with Required[SomeModel]错误:

  

类型参数[String,OwnerType]不符合trait Field的类型参数边界[ThisType,OwnerType&lt ;:net.liftweb.record.Record [OwnerType]]

...即使StringField.ThisTypeStringString.OwnerTypeRecord[SomeModel]的子类,SomeModelMongoRecord[SomeModel]的子类。 - 我输了。

P.S。这与Lift Record: empty value for required field but no validation errors

有关

1 个答案:

答案 0 :(得分:1)

以下在SBT控制台中编译。

import net.liftweb.util._
import net.liftweb.record._
import net.liftweb.record.field._

trait Required extends StringTypedField {

  override def validations: List[ValidationFunction] = valMinLen(1, "Required!") _ :: super.validations

}

class TestRecord extends Record[TestRecord] {

    val meta = TestRecord

    object testField extends StringField(this, 255) with Required

}

object TestRecord extends TestRecord with MetaRecord[TestRecord]