Scala Play Forms:使用HLists来绕过22个字段限制

时间:2016-11-08 08:14:38

标签: scala slick playframework-2.5

Slick使用一种与HLists的hack来管理超过22列的表,例如这个(自动生成的)行模型构造函数:

type SamplesRow = HCons[Int,HCons[String,HCons[Option[String],HCons[Int,HCons[String,HCons[Int,HCons[Int,HCons[Option[Int],HCons[Option[Float],HCons[Option[Float],HCons[Option[String],HCons[Option[String],HCons[Boolean,HCons[Option[String],HCons[Option[String],HCons[Option[String],HCons[Option[String],HCons[Option[String],HCons[Option[Int],HCons[Option[Float],HCons[Option[Float],HCons[Option[Float],HCons[Option[String],HCons[Option[String],HNil]]]]]]]]]]]]]]]]]]]]]]]]

def SamplesRow(id: Int, name: String, shortName: Option[String] = None, sampleTypeId: Int, receivedDate: String, projectId: Int, taxoId: Int, quantifMethodId: Option[Int] = None, concentration: Option[Float] = None, volume: Option[Float] = None, description: Option[String] = None, comment: Option[String] = None, istrashed: Boolean = false, commentCustomer: Option[String] = None, createdAt: Option[String] = None, updatedAt: Option[String] = None, createdBy: Option[String] = None, updatedBy: Option[String] = None, poId: Option[Int] = None, `260280Ratio`: Option[Float] = None, `260230Ratio`: Option[Float] = None, rin: Option[Float] = None, concUpdatedAt: Option[String] = None, concUpdatedBy: Option[String] = None): SamplesRow = {
  id :: name :: shortName :: sampleTypeId :: receivedDate :: projectId :: taxoId :: quantifMethodId :: concentration :: volume :: description :: comment :: istrashed :: commentCustomer :: createdAt :: updatedAt :: createdBy :: updatedBy :: poId :: `260280Ratio` :: `260230Ratio` :: rin :: concUpdatedAt :: concUpdatedBy :: HNil
}

我可以使用相同的技巧让表格保留24个值吗?喜欢

val tableForm: Form[SamplesRow] = Form(
  mapping(
    ID -> ignored(-1),
    NAME -> text,
    SHORT_NAME -> optional(text),
    SAMPLE_TYPE_ID -> number,
    RECEIVED_DATE -> default(text, NOW),
    PROJECT_ID -> number,
    TAXO_ID -> number,
    QUANTIF_METHOD_ID -> optional(number),
    CONCENTRATION -> optional(of[Float]),
    VOLUME -> optional(of[Float]),
    DESCRIPTION -> optional(text),
    COMMENT -> optional(text),
    IS_TRASHED -> default(boolean, false),
    COMMENT_CUSTOMER -> optional(text),
    CREATED_AT -> optional(text),
    UPDATED_AT -> optional(text),
    CREATED_BY -> optional(text),
    UPDATED_BY -> optional(text),
    PO_ID -> optional(number),
    RATIO_260_280 -> optional(of[Float]),
    RATIO_260_230 -> optional(of[Float]),
    RIN -> optional(of[Float]),
    CONC_UPDATED_AT -> optional(text),
    CONC_UPDATED_BY -> optional(text)
  )(SamplesRow)(???)
)

我觉得上面的构造函数def SamplesRow可以用作apply方法,但我可以用什么作为“unapply”?

我知道我应该使用嵌套映射,但是我无法将结果直接映射到Slick行模型,并且编写100行代码来实现转换听起来很愚蠢,这样我就可以进行插入。 / p>

1 个答案:

答案 0 :(得分:0)

我很想完全摆脱Forms并用自定义的JsObject解析替换它们:

// Controller Action:
val content = request.body.asJson
val row = rowFromJson(content)

// Somewhere else
import play.api.libs.json._
def rowFromJson(j: JsObject): SamplesRow = {
  SamplesRow(
    (j \ "id").as[Int],
    (j \ "name").as[String]
    ...
  )
}

其中SamplesRow是表Samples#TableElementType的Slick Samples <: AbstractTable[_]