在为这两个模型编写编写器时,我收到错误。
以下是我的模特:
case class Ad (
var id: Long,
var account: Account,
...
var pictures: List[Picture]) extends Model
object Ad {
implicit val adWrites = Json.writes[Ad]
}
case class Picture(
var id: Long,
var ad: Ad) extends Model
object Picture {
implicit pictureWrites = Json.writes[Picture]
implicit def listPictureWrites[PictureScala](implicit fmt: Writes[PictureScala]): Writes[List[PictureScala]] = new Writes[List[PictureScala]] {
def writes(ts: List[PictureScala]) = JsArray(ts.map(t => Json.toJson(t)(fmt)))
}
}
这不起作用。我收到了以下消息:在pictureWrites(=>“没有可用于models.AdScala的隐式写入。”)和adWrites(=>“没有针对java.util.List [models.PictureScala的隐式写入]可用。 “)。
我认为这是因为每个编写者都需要其他case类的write方法。但是我该如何解决这个问题呢?如果我对“广告”和“图片”进行评论,则可以正常使用。
答案 0 :(得分:1)
Json.writes
宏在这种情况下不起作用,因为你的类型是递归的。但是,明确定义Writes
个实例并不算太糟糕:
import play.api.libs.functional.syntax._
import play.api.libs.json._
// Next two lines for the sake of a complete working example.
trait Model
type Account = String
case class Ad (
var id: Long,
var account: Account,
var pictures: List[Picture]
) extends Model
object Ad {
implicit val adWrites: Writes[Ad] = (
(__ \ 'id).write[Long] and
(__ \ 'account).write[Account] and
(__ \ 'pictures).write[List[Picture]]
)(unlift(Ad.unapply))
}
case class Picture(var id: Long, var ad: Ad) extends Model
object Picture {
implicit val pictureWrites: Writes[Picture] = (
(__ \ 'id).write[Long] and
(__ \ 'ad).lazyWrite(Ad.adWrites)
)(unlift(Picture.unapply))
}
然后:
scala> val ad1 = Ad(1, "foo", Nil)
ad1: Ad = Ad(1,foo,List())
scala> val ad2 = Ad(2, "bar", List(Picture(1, ad1)))
ad2: Ad = Ad(2,bar,List(Picture(1,Ad(1,foo,List()))))
scala> Json.prettyPrint(Json.toJson(ad2))
res8: String =
{
"id" : 2,
"account" : "bar",
"pictures" : [ {
"id" : 1,
"ad" : {
"id" : 1,
"account" : "foo",
"pictures" : [ ]
}
} ]
}
特别注意lazyWrite
中的pictureWrites
,这是递归所必需的。