2015-06-11 13 views
8

Ho questo codice per un API che mi permette di recuperare e oggetto dal database e restituisce un oggetto JSON utilizzando Slick 3.0:Slick 3.0: modo idiomatico per ottenere risultati dal database interno di Opzione (Scala Gioca quadro)

// 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) 
} 
// Controller 

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

il problema è che se interrogo un oggetto che non è nel database, ottengo un'eccezione. Quello che vorrei fare è quello di ottenere un Option all'interno della Future che viene restituito dalla Model al fine di essere in grado di scrivere qualcosa del genere:

// 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))) 
    } 
    } 
} 

Ha senso?

risposta

10

Chiamate headOption sul vostro risultato, invece di head:

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

+0

Non potrebbe essere più semplice. Grazie! – Daniel

+0

Questo mi ha preoccupato per un po 'di tempo. Grazie. –

Problemi correlati