Slick 3.0:从Option(Scala Play Framework)内的数据库获取GET结果的惯用方法

Dan*_*iel 8 scala playframework slick slick-3.0

我有这个代码API允许我从数据库中检索和对象并JSON使用Slick 3.0以下命令返回一个对象:

// Model

case class Thing(id: Option[Int], name: String)

object Thing {
  implicit val teamWrites = Json.writes[Thing]
}

class Things(tag: Tag) extends Table[Thing](tag, "thing") {
  def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
  def name = column[String]("name")
  def * = (id.?, name) <> ((Thing.apply _).tupled, Thing.unapply)
}

object Things {
  private val db = Database.forConfig("h2mem1")
  private object things extends TableQuery[Things](tag ? new Things(tag)) { 
    def all = things.result 
  }
  private def filterQuery(id: Int): Query[Things, Thing, Seq] = 
    things.filter(_.id === id)

  def findById(id: Int): Future[Thing] = db.run(filterQuery(id).result.head)
}
Run Code Online (Sandbox Code Playgroud)
// Controller

class ThingController extends Controller {
  def get(id: Int) = Action.async {
    Things.findById(id).map(thing => Ok(Json.obj("result" -> thing)))
  }
}
Run Code Online (Sandbox Code Playgroud)

问题是如果我查询不在数据库中的对象,我会得到一个例外.我想做的是获取从Option内部Future返回的内容Model,以便能够编写如下内容:

// Controller

class ThingController extends Controller {
  def get(id: Int) = Action.async {
    Things.findById(id).map {
      case None => NotFound(Json.obj("error" -> "Not Found"))) 
      case Some(thing) => Ok(Json.obj("result" -> thing)))
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

是否有意义?

Rom*_*man 10

只需拨打headOption您的结果,而不是head:

def findById(id: Int): Future[Option[Thing]] = db.run(filterQuery(id).result.headOption)