我正在使用播放框架和光滑,播放框架在表单验证中使用案例映射但是有些值我不需要验证,因为它们不是由用户输入的,例如ID&完成的日期在后端提供。
最后我希望有一个这样的类案例,提供给Slick并与我的表一起使用。
case class Order(id: Long, order: String, date: Date)
对于Play的表格验证,我会提供一个单独的案例类:
case Class inputableOrder(order: String)
然后我可以创建Order类,它将从inputableOrder中获取变量并将其添加到Order类中吗?
case class Order(id: Long, date: Date) // <- some way to add the variable from inputableOrder?
我只是想阻止重复,但我仍然需要两个不同的案例类(一个用于表单验证,另一个用于处理数据库)。
有没有办法修改现有的case类,删除变量或修改变量类型?
答案 0 :(得分:4)
我认为你有几种选择:
将InputableOrder
作为Order
的一部分:
case class InputableOrder(order: String) // ...
case class Order(input: InputableOrder, id: Long, date: Date) // ..
这可能是最惯用的解决方案。但如果你后来发现InputableOrder
需要一些不应该在Order
中的内容,那么它就会变得不灵活。
使Order
成为InputableOrder
的子类。在这种情况下,将参数传递给超类时会有一些代码重复,而超类不能是case
类,所以你必须将它声明为常规类并自己创建一个提取器:
class InputableOrder(val order: String) // ...
object InputableOrder {
def unapply(o: InputableOrder): Option[String] = Some(o.order);
// if you have more than one constructor arguments, return
// a tuple like Option[(String,String)] etc.
}
case class Order(override val order: String, id: Long, date: Date)
extends InputableOrder(order) // ...
同样,可能会出现与前一点相同的问题。
使类不同并创建辅助方法以在它们之间进行转换。选择取决于您的设计,但我发现此解决方案最灵活:
case class InputableOrder(order: String);
case class Order(order: String, id: Long, date: java.util.Date) {
// An additional constructor to use when converting from Inputable:
def this(other: InputableOrder, id: Long, date: java.util.Date) =
this(other.order, id, date);
// Update this instance with `other`:
def this(that: Order, other: InputableOrder) =
this(other, that.id, that.date);
def toInput = InputableOrder(order);
}
这样,您只需提供缺少的字段即可从Order
创建InputableOrder
,反之亦然。您需要编写一次这些辅助方法/构造函数,但使用它们很容易。
您还可以使用隐式方法,例如
implicit def toInput(other: InputableOrder): Order = other.toInput;
让事情变得更加轻松。