I would like to query an object by id
, but if a fooId
is also provided then I'd like to include it in the query.
def getById(id: Long, fooIdOpt: Option[Long]): Future[Option[Bar]] = {
val query = for {
b <- bars if b.id === id && fooIdOpt.fold(true)(b.fooId === _)
} yield { // Compiler error here ^
b
}
db.run(query.result.headOption)
}
The issue here is that fooIdOpt.fold(true)(b.fooId === _)
needs to return a Rep[Boolean]
, but I'm initializing the fold with a Boolean
- a clear type violation of fold
's method signature.
However I can't seem to find a way to pass a Rep[Boolean]
that evaluates to true
in as the fold initializer. Shooting in the dark, I've tried Rep(true)
, and LiftedLiteral[Boolean](true)
, but neither quite work.
I could abandon fold
entirely and go with:
b <- bars if {
val rep1 = b.id === id
fooIdOpt.map(fooId => rep1 && b.fooId === fooId).getOrElse(rep1)
}
But that just seems so overly complicated, and a fooIdOpt match { case Some ...
wouldn't look much better.
Rep[Boolean]
literal that always evaluates to true
?fold
, map
, or match
above that will allow me to build a query that optionally compares a fooId
value?As you've already figured out, the ifEmpty
value type for fold
needs to match that of b.fooId === _
, which is Rep[Boolean]
. One approach would be to apply bind
to the ifEmpty
value as shown below:
val query = for {
b <- bars if b.id === id && fooIdOpt.fold(true.bind)(b.fooId === _)
} yield b