如何使用Forms在Play Framework(2.4.0)中获取子记录(案例类)ID [英] How to get child record (case class) ID in Play Framework (2.4.0) using Forms

查看:103
本文介绍了如何使用Forms在Play Framework(2.4.0)中获取子记录(案例类)ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

恐怕我还没有看到.

必须有一种使用预期使用的工具的方式来获取一系列项目"的子记录(许多到一个典型的关系数据库资料)的ID

There must be a way, using the tools as they are intended to be used, to get the ID of a child record (many-to-one typical relational database stuff) of a series of "items"

我可以在父类的case类中创建一个表单"(映射),没有问题.

I can create a "form" (mapping) in the case class of the parent no problem.

lazy val aForm = Form( mapping( "ID" -> ignored(id), "firstName" -> nonEmptyText, "lastName" -> nonEmptyText, "listOfEmails" -> seq(email), "statusID" -> ignored(0l), "roleID" -> default(longNumber, roleID), "timezoneID" -> default(longNumber, timezoneID) (User.apply) (User.unapply) )

lazy val aForm = Form( mapping( "ID" -> ignored(id), "firstName" -> nonEmptyText, "lastName" -> nonEmptyText, "listOfEmails" -> seq(email), "statusID" -> ignored(0l), "roleID" -> default(longNumber, roleID), "timezoneID" -> default(longNumber, timezoneID) (User.apply) (User.unapply) )

现在我们可以将其分解为以下内容:

Now we can break this out a tad and have the following:

lazy val aForm = Form( mapping( "ID" -> ignored(id), "firstName" -> nonEmptyText, "lastName" -> nonEmptyText, "listOfEmails" -> mapping( "email" -> email, "userID" -> ignored(id), "emailTypeID" -> longNumber) (UserEmail.apply)(UserEmail.unapply), "statusID" -> ignored(0l), "roleID" -> default(longNumber, roleID), "timezoneID" -> default(longNumber, timezoneID) (User.apply) (User.unapply) )

lazy val aForm = Form( mapping( "ID" -> ignored(id), "firstName" -> nonEmptyText, "lastName" -> nonEmptyText, "listOfEmails" -> mapping( "email" -> email, "userID" -> ignored(id), "emailTypeID" -> longNumber) (UserEmail.apply)(UserEmail.unapply), "statusID" -> ignored(0l), "roleID" -> default(longNumber, roleID), "timezoneID" -> default(longNumber, timezoneID) (User.apply) (User.unapply) )

以上内容与帮助程序"形式一起使用,可确保准备输入新输入的最少数量的空白.

The above is used with a form "helper" which ensure a minimum number of blanks are ready to go for new inputs.

我们甚至可以获得更多的创意(DRY),并这样做:

And we can even get a tad more creative (DRY) and do like so:

lazy val aForm = Form( mapping( "ID" -> ignored(id), "firstName" -> nonEmptyText, "lastName" -> nonEmptyText, "listOfEmails" -> seq(UserEmail.EMPTY.form(id).mapping), "statusID" -> ignored(0l), "roleID" -> default(longNumber, roleID), "timezoneID" -> default(longNumber, timezoneID) (User.apply) (User.unapply) )

lazy val aForm = Form( mapping( "ID" -> ignored(id), "firstName" -> nonEmptyText, "lastName" -> nonEmptyText, "listOfEmails" -> seq(UserEmail.EMPTY.form(id).mapping), "statusID" -> ignored(0l), "roleID" -> default(longNumber, roleID), "timezoneID" -> default(longNumber, timezoneID) (User.apply) (User.unapply) )

其中案例类UserEmail中的表单被重用",而不是在父案例类中被重复". EMPTY只是我用作每个case类的常量的对象.

where the form inside the case class UserEmail is "reused" instead of having it "repeated" in the parent case class. EMPTY is just an object that I use as a constant for each case class.

请注意,尽管这会创建空白"表单条目,但它们都是在表单/屏幕上填充的数据.非常感谢这个小帮手(repeatWithIndex- https://gist.github.com/benoit-ponsero/4484313 ),每个人都说真的不需要!(???)

Note that even though this creates "blank" form entries they are data filled on the form/screen. Thanks in no small part to this little helper (repeatWithIndex -- https://gist.github.com/benoit-ponsero/4484313) which everyone says isn't really needed!(???)

我还无法理解的是我如何使用Seq[UserEmail](当然,在父级User案例类中也可以使用它),并将其ID传播到食物链中,并往返于控制器上的POST?

What I haven't been able to grok yet is how I take a Seq[UserEmail] (which of course is available inside the parent User case class) and propagate it's ID's down the food chain and back round-trip to the POST on the controller?

目前,我可以使用zip进行此时髦的操作,并创建一个加倍的列表,然后再将其与foreach服务器端重新组合在一起,但这只是令人讨厌".

Currently I can do this funky thing with zip and create a doubled list and piece the bits back together again with a foreach server side but this just "feels yucky".

根据所涉及的数据(我想对比简单电子邮件地址复杂得多的所有类型的实体执行此操作),如果给定记录是添加,更改或删除,则可能很难准确确定.甚至假设有可能在逐案的基础上实现自定义工作也需要做很多工作(还有很多不必要的继承债务来启动!)

Depending upon the data involved (I want to do this for all kinds of entities far more complex than simple email addresses) it could get difficult to ascertain with exactitude if any given record is an add, change or delete. Even assuming it was possible this is a lot of work to implement custom work on a case by case basis (and a lot of needless(?) debt inherited to boot!)

有人能破解吗,还想分享吗?

Anyone cracked this nut yet and care to share?

推荐答案

好-我有一个解雇方案.

Ok - I have one firing solution.

首先,我对寺庙进行了重新设计,为每个元素添加了隐藏字段((!).

First I've reworked the temple to include hidden fields (yuck!) for each element.

然后在apply内部添加如下逻辑:

Then inside of apply I've added logic like so:

def apply( id: Long, firstName: String, lastName: String, emails: Seq[UserEmail], statusID: Long, roleID: Long, timezoneID: Long) = { trace("emails: {}", emails) emails foreach { x => x.writeDB trace(x) } new User(id, firstName, lastName, statusID, roleID, timezoneID) }

def apply( id: Long, firstName: String, lastName: String, emails: Seq[UserEmail], statusID: Long, roleID: Long, timezoneID: Long) = { trace("emails: {}", emails) emails foreach { x => x.writeDB trace(x) } new User(id, firstName, lastName, statusID, roleID, timezoneID) }

,然后在unapply方法

def unapply(x: User): Option[(Long, String, String, Seq[UserEmail], Long, Long, Long)] = Some(x.id, x.firstName, x.lastName, x.tkEmails, x.statusID, x.roleID, x.timezoneID)

def unapply(x: User): Option[(Long, String, String, Seq[UserEmail], Long, Long, Long)] = Some(x.id, x.firstName, x.lastName, x.tkEmails, x.statusID, x.roleID, x.timezoneID)

在这两种方法之间似乎发生了魔术.请注意此处的非对称性,因为在案例类构造函数中,我Seq[UserEmail]作为val.它由unapply静默删除,并由apply处理.

It appears that between these two methods the magic occurs. Notice the assymetry here in that I do not have the Seq[UserEmail] as a val in the case class constructor. It is silently dropped by the unapply and processed by the apply.

内部"表格userEmail必须这样实现:

The "inner" form userEmail has to be implemented like so:

def form(userID: Long) = Form( mapping( "ID" -> default(longNumber, id), "userID" -> default(longNumber, userID), "address" -> optional(email) )(UserEmail.apply)(UserEmail.unapply) )

def form(userID: Long) = Form( mapping( "ID" -> default(longNumber, id), "userID" -> default(longNumber, userID), "address" -> optional(email) )(UserEmail.apply)(UserEmail.unapply) )

希望我早就知道了!

这感觉与优雅相去甚远(我不得不考虑很多代码-这是一个精简的示例,只是为了展示相关概念),但至少它是可行的-仍然很乐意如果可能的话,看到更多的玩游戏"!

This feels far too far from elegant (There is a LOT more code that I have to take into account - this is a radically stripped down example just to show the relevant concept) but at least it is workable - still would love to see something far more "play-ish" if possible!

这篇关于如何使用Forms在Play Framework(2.4.0)中获取子记录(案例类)ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆