Skip to content

Instantly share code, notes, and snippets.

@leon
Created May 7, 2013 18:58

Revisions

  1. leon revised this gist May 7, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion UsersController.scala
    Original file line number Diff line number Diff line change
    @@ -6,6 +6,6 @@ import play.api.libs.json._
    import extensions.JsonTransforms._
    import reactivemongo.bson.BSONObjectID

    object Users extends RestController[User] {
    object UsersController extends RestController[User] {
    /* This should automatically get the list function
    }
  2. leon created this gist May 7, 2013.
    64 changes: 64 additions & 0 deletions MongoModel.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,64 @@
    package models

    import scala.concurrent.{Future, ExecutionContext}
    import reactivemongo.core.commands.{GetLastError, LastError}
    import play.modules.reactivemongo.json.collection.JSONGenericHandlers
    import reactivemongo.api.collections.GenericCollection
    import play.api.libs.json.Json.JsValueWrapper

    // Reactive Mongo imports
    import reactivemongo.api._
    import reactivemongo.bson._

    // Reactive Mongo plugin
    import play.modules.reactivemongo._

    // Play Json imports
    import play.api.libs.json._

    import play.api.Play.current

    trait MongoModel[T] extends GenericCollection[JsObject, Reads, Writes] with JSONGenericHandlers with CollectionMetaCommands {

    import scala.reflect._
    private val ct = classTag[T]
    def name: String = ct.runtimeClass.getName.toLowerCase + "s"

    def db: DB = ReactiveMongoPlugin.db
    def failoverStrategy: FailoverStrategy = FailoverStrategy()

    implicit def format: Format[T] = Json.format[T]

    private val ID = "_id"

    implicit private def ec: ExecutionContext = ExecutionContext.Implicits.global

    def find(query: (String, JsValueWrapper)*): Future[List[T]] = find(Json.obj(query: _*)).cursor[T].toList
    def findOption(query: (String, JsValueWrapper)*): Future[Option[T]] = find(query).cursor[T].headOption

    def findById(id: BSONObjectID): Future[Option[T]] = findOption(ID -> id)
    def findById(id: String): Future[Option[T]] = findById(BSONObjectID(id))

    def update(id: BSONObjectID, model: T): Future[LastError] = update(Json.obj(ID -> id), model, upsert=true)
    def update(id: String, model: T): Future[LastError] = update(BSONObjectID(id), model)

    def remove(query: (String, JsValueWrapper)*): Future[LastError] = remove(query)
    def remove(id: BSONObjectID): Future[LastError] = remove(Json.obj(ID -> id))
    def remove(id: String): Future[LastError] = remove(BSONObjectID(id))

    /*
    Methods from JSONCollection
    */
    def save(doc: JsObject)(implicit ec: ExecutionContext): Future[LastError] = save(doc, GetLastError())
    def save(doc: JsObject, writeConcern: GetLastError)(implicit ec: ExecutionContext): Future[LastError] = {
    import reactivemongo.bson._
    import play.modules.reactivemongo.json.BSONFormats
    (doc \ "_id" match {
    case JsUndefined(_) => insert(doc + ("_id" -> BSONFormats.BSONObjectIDFormat.writes(BSONObjectID.generate)), writeConcern)
    case id => update(Json.obj("_id" -> id), doc, writeConcern, upsert = true)
    })
    }
    def save[T](doc: T, writeConcern: GetLastError = GetLastError())(implicit ec: ExecutionContext, writer: Writes[T]): Future[LastError] = {
    save(writer.writes(doc).as[JsObject], writeConcern)
    }
    }
    22 changes: 22 additions & 0 deletions RestController.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    package controllers

    import play.api.mvc._
    import play.api.libs.json._

    import reactivemongo.bson._

    import models._
    import extensions.JsonTransforms._

    trait RestController[T <: MongoModel] extends Controller {

    def list = Action { implicit request =>
    // How would I get the companion object to be able to call the method find on it?
    val f = T.find()
    Async {
    f.map { users =>
    Ok(Json.toJson(users))
    }
    }
    }
    }
    22 changes: 22 additions & 0 deletions User.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,22 @@
    package models

    import play.api.libs.json._
    import play.api.libs.functional.syntax._
    import reactivemongo.bson.BSONObjectID

    import play.modules.reactivemongo.json.BSONFormats._
    import play.modules.reactivemongo.ReactiveMongoPlugin
    import play.modules.reactivemongo.json.collection.JSONCollection

    import play.api.Play.current

    case class User(
    email: String,
    firstName: String,
    lastName: String,
    _id: Option[BSONObjectID]
    ) {
    val name = s"$firstName $lastName"
    }

    object User extends MongoModel[User]
    11 changes: 11 additions & 0 deletions UsersController.scala
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    package controllers

    import play.api.mvc._
    import models._
    import play.api.libs.json._
    import extensions.JsonTransforms._
    import reactivemongo.bson.BSONObjectID

    object Users extends RestController[User] {
    /* This should automatically get the list function
    }