编译错误:
No Json serializer found for type Seq[(models.Account, models.Company)]. Try to implement an implicit Writes or Format for this type.
如何为连接查询的结果定义隐式写入?
控制器:
def someEndpoint = Action.async { implicit request =>
val query = for {
a <- accounts if a.id === 10
c <- companies if a.companyID === c.id
} yield (a, c)
db.run(query.result).map(rows => Ok(Json.toJson(rows))) // Causes compilation error
}
我的每个模特(账户和公司)都有自己的隐式写作(这里是公司的一个):
case class Company(id: Int, name: String)
object Company {
implicit val writes = new Writes[Company] {
def writes(company: Company): JsValue = {
Json.obj(
"id" -> company.id,
"name" -> company.name
)
}
}
}
是否可以动态处理连接的序列化?我有很多事情要加入......我是否需要为每个组合明确定义writes
?
答案 0 :(得分:1)
Writes.seq
会帮助您
小作家
val w = (
(__ \ "account").write[Account] and
(__ \ "company").write[Company]
).tupled
可帮助您使用
将Seq[(models.Account, models.Company)]
转换为JsValue
Writes.seq(w).writes(rows)
和最后一个命令将是
db.run(query.result).map(rows => Ok(Writes.seq(w).writes(rows))
或更明确的变体
db.run(query.result)
.map(
_.map{
case (a,c) => Json.obj("account" -> a, "company" -> c)
}
)
.map(rows =>
Ok(JsArray(rows))
)
它是一样的,但你自己为每一行创建了对象。
答案 1 :(得分:0)
我认为您希望JSON中的查询响应类似于
[
{
"account" : { "number": "123", "companyID" : 1 },
"company" : { "id" : 1, "name" : "My company"}
} , ...
]
问题是查询的响应只是一个元组,所以&#34; account&#34;和&#34;公司&#34;不容易计算。
您可以使用已连接的数据创建新的案例类,而不是元组,但我知道您希望避免这种情况。在这种情况下,你可以使用一个可以自动转换为JSON的Map来代替元组。
额外:为案例类创建编写器非常简单
import play.api.libs.json._
implicit val personWrites = Json.writes[Person]
参考:https://www.playframework.com/documentation/2.4.x/ScalaJsonInception