combining multiple pipes

13 views
Skip to first unread message

alexmnyc

unread,
Sep 4, 2013, 2:36:44 PM9/4/13
to rogue...@googlegroups.com
What is the best way to construct a query with dynamically added pipes similar to

var query =  User.where(_.id eqs someId)

if (something) query = query.modify(_.likes push List("like"))

if (somethingElse) query= query.modify(_.dislikes push List("disklike"))

query.updateMulti()


Jorge Ortiz

unread,
Sep 6, 2013, 3:25:08 PM9/6/13
to rogue...@googlegroups.com
At Foursquare, we have some helper methods/implicits for this situation. With the following code:

    sealed class Identity[A](protected val _value: A) {
      def applyIf[B >: A](pred: Boolean, f: A => B): B = if (pred) f(_value) else _value
      def applyOpt[B](opt: Option[B])(f: (A, B) => A): A = opt.map(b => f(_value, b)).getOrElse(_value)
    }

    object Identity {
      implicit def wrapIdentity[A](anything: A): Identity[A] = new Identity(anything)
    }

Then, as long as the wrapIdentity implicit is in scope, you can write code like:

    val query = (User
      .where(_.id eqs someId)
      .applyIf(something, _.modify(_.likes push List("like"))))
      .applyIf(somethingElse, _.modify(_.dislikes push List("dislike"))))

    query.updateMulti()

The inferred type usually does the Right Thing. Sometimes you can get yourself in a pickle with the phantom types, but there's usually a way out of it.

Usage of the similar applyOpt method is left as an exercise.

--j



--
You received this message because you are subscribed to the Google Groups "rogue-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rogue-users...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Jorge Ortiz

unread,
Sep 6, 2013, 3:29:10 PM9/6/13
to rogue...@googlegroups.com
Open mouth, insert foot. This particular code will get you into a pickle with the types.

You can use the .noop() method to turn any query into a modify query. So what you really want is more like:

    val query = (User
      .where(_.id eqs someId)
      .noop()
      .applyIf(something, _.modify(_.likes push List("like"))))
      .applyIf(somethingElse, _.modify(_.dislikes push List("dislike"))))

    query.updateMulti()

Reply all
Reply to author
Forward
0 new messages