Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Play 2.0 models best practices

I am looking for best practices regarding models and ways to persist objects in database with play 2.0. I have studied the Play and typesafe samples for play 2.0 using scala.

What I understand is :

  • The model is defined in a case class
  • All the insert/update/delete/select are defined in the companion object of this case class

So if I need to update my Car object to define a new owner i will have to do:

val updatedCar = myCar.copy(owner=newOwner)
Car.update(updatedCar)
// or
Car.updateOwner(myCar.id.get, newOwner)

I am wondering why the update or delete statements are not in the case class itself:

case class Car(id: Pk[Long] = NotAssigned, owner: String) {
    def updateOwner(newOwner: String) {
        DB.withConnection { implicit connection =>
            SQL(
                """
                update car
                set owner = {newOwner}
                where id = {id}
                """
            ).on(
                'id -> id,
                'newOwner -> newOwner
            ).executeUpdate()
        }
        copy(owner = newOwner)
    }
}

Doing so would permit to do:

val updatedCar = myCar.updateOwner(newOwner)

Which is what I used to do with Play 1.X using Java and JPA. Maybe the reason is obvious and due to my small knowledge of Scala.

like image 278
kheraud Avatar asked Oct 08 '22 21:10

kheraud


1 Answers

I think part of the reason is the favoring of immutability in functional languages like Scala.

In your example, you modify 'this.owner'. What's your equivalent operation look like for a delete, and what happens to "this"?

With a companion object, it seems a bit more clear that the passed object (or ID) is not modified, and the returned object or ID is the relevant result of the operation.

Then also, I think another part of the issue is that your example requires an instance first. When you delete an Object, what if you just want to delete by Id you got off a form, and don't want to first build a whole instance of the object you intend to delete?

I've been playing with play2.0 with mongo, and my companion objects look like:

object MyObject extends SalatDAO[MyObject,ObjectId] (collection = getCollection("objectcollection")) { }

These companion objects inherit CRUD like operations from SalatDAO (MyObject.save(), MyObject.find(), etc). I'm not entirely clear on how it is implemented internally, but it works nicely.

like image 191
nairbv Avatar answered Oct 10 '22 22:10

nairbv