在绑定之前转换anorm(播放框架)值

时间:2014-07-10 18:43:17

标签: scala playframework-2.0

我有一个代表我的域名的案例类:

case class MyModel(rawValue: String, transformedValue: String)

rawValue映射到数据库中的值,并且已正确解析和绑定。我要做的是将transformedValue添加到我的模型中:这个值只是我在rawValue上执行的一些任意转换。它映射到数据库/查询中的任何数据。

我有一个解析器(在添加transformedValue之前),如下所示:

val parser = {
  get[String]("rawValue") map {
    case rawValue => MyModel(rawValue)
  }
}

由于MyModel是不可移植的,我无法在创建后插入transformedValue,所以最好的方法是什么,在哪里添加并添加此转换(例如添加ad-hoc值到模型)最好不使用变量?

来自Java,我可能只是在域类中添加了一个getTransformedValue getter,它在rawValue属性上执行此转换。

3 个答案:

答案 0 :(得分:2)

由于transformedValue似乎是派生属性,而不是构造函数中提供的属性,因此您可以将其定义为函数体中的属性,可能使用lazy限定符这样它只能按需计算(例如只计算一次):

case class MyModel(rawValue: String) {
  lazy val transformedValue: String = {
    // Transformation logic, e.g.
    rawValue.toLowerCase()
  }
}

val在定义时进行评估;调用def时会对其进行评估。第一次访问时会评估lazy val

在很少需要昂贵的计算或逻辑需要的情况下使用lazy可能是合适的。但对于大多数情况,应使用常规valQuoting

  

lazy val 免费(甚至便宜)。只有在绝对需要懒惰才能正确使用时才使用它,而不是用于优化。

答案 1 :(得分:1)

我不明白你为什么不在解析器本身进行转换:

def transformation(rawValue: String): String = ...

val parser = {
    get[String]("rawValue") map {
        case rawValue => MyModel(rawValue, transformation(rawValue))
    }
}

或者如果您因某些原因不想在那里进行,可以使用copy创建一个新值MyModel的副本:

val model = MyModel("value", ..)

val modelWithTransform = model.copy(transformedValue = transformation(model.rawValue))

您还可以重载apply以在配对对象中自动应用转换:

case class MyModel(rawValue: String, transformedValue: String)

object MyModel {

    def apply(value: String): MyModel = MyModel(rawValue, transformation(rawValue))

    val parser = {
        get[String]("rawValue") map {
            case rawValue => MyModel(rawValue)
        }
    }
}

MyModel可能是不可变的,但您可以随时创建另一个副本,并更改​​一些值。

答案 2 :(得分:0)

事实证明它比我想象的要容易,解决方案确实看起来像我在Java中所说的那样:

我只是向MyModel添加一个执行此转换的函数:

case class MyModel(rawValue: String) {
  def transformedValue = {
    // do the transformation here and return it
  }
}
相关问题