How to simplify your action’s validation code in Play Framework 2 (with Scala of course)

In web development you very often want to do some checks if the data passed through parameters are valid. I’m not talking about having valid format but if for example the corresponding entry exists or if the user has the right to access that information or not. I’ll be a bit more specific by using an example and you’ll get my point. Ok, let’s consider that we want to make a web app which manages devices and users. A device has a unique id and a name. A user has a unique id, a name and a set of devices attached to him. Let’s assume we wrote all the necessary code and we want to provide an action that attaches a device to a user. How would we do that? My first approach would be something like this:

object Users extends Controllers {

  def attachDevice(user_id : Long, device_id : Long) = Action {
    models.User.getById(user_id).map { user_id =>
      models.Device.getById(device_id).map { device_id =>
        if (models.User.attach(user_id, device_id))
          Ok("succeeded")
        else
          InternalServerError
      }.getOrElse { BadRequest("Invalid device id") }
    }.getOrElse { BadRequest("Invalid user id") }
  }

}

That’s fine! It’s not a bad approach. We do all the necessary tests. Code is more or less readable. It’s clear what we return in each case. But what happens when we want to have another action that needs to check if the user_id or device_id is valid? Would we rewrite them?

Not really! We would refactor them!

Great! Let’s create a trait Security and put our validations there.

trait Security {
  import play.api.mvc.Results._

  def withValidDevice(device_id : Long)(result : Result) = {
    if (models.Device.getById(device_id).nonEmpty)
      result
    else
      BadRequest( "Invalid device id" )
  }

  def withValidUser(user_id : Long)(result : Result) = {
    if (models.User.getById(user_id).nonEmpty)
      result
    else
      BadRequest( "Invalid user id" )
  }

  def IsValidUserAndDevice(user_id : Long, device_id : Long)(f: Request[AnyContent] => Result) = Action { req =>
    withValidUser(user_id) {
      withValidDevice(device_id) {
        f(req)
      }
    }
}

That’s it! Let’s use it now in our controller to simplify the code. Can you guess what it would be?

object Users extends Controllers with Security {

  def attachDevice(user_id : Long, device_id : Long) = IsValidUserAndDevice(user_id, device_id) {
    if (models.User.attach(user_id, device_id))
      Ok("succeeded")
    else
      InternalServerError
  }
}

This is a lot cleaner isn’t it? But what if we want to process a POST request with form data? How would we use our validations? It turns out that it’s not so hard to do (see code below).

object Users extends Controllers {

  import play.api.data.Forms._
  import play.api.data._

  case class AttachData(user_id : Long, device_id : Long)

  val attachForm = Form(
    mapping(
      "user_id" -> longNumber,
      "device_id" -> longNumber
    )(AttachData.apply)(AttachData.unapply)
  )

  def attachDevice(user_id : Long, device_id : Long) = Action {
    shareForm.bindFromRequest.fold(
      formWithErrors => BadRequest( formWithErrors.errorsAsJson ),
      data => {
        withValidUser(data.user_id) {
          withValidDevice(data.device_id) {
            if (models.User.attach(user_id, device_id))
              Ok("succeeded")
            else
              InternalServerError
          }
        }
      }
    )
  }
}

We could for improvement define a method withValidUserAndDevice in our Security trait and then simplify the POST request code as well.

Conclusion

There is no very special conclusion telling the truth but I just wanted to point out this pattern with defining two validation methods:

  1. A method that returns an Action and can simplify the code of the GET requests
  2. A method that returns a Result which can simplify the POST requests and is flexible enough to be used in every action you want

As always, I hope you’ll find this blog entry useful and will help you simplify your validation code with Play Framework 2 and Scala 🙂

Advertisements

Change brightness of my laptop screen through command line

Unfortunately the Fn buttons for brightness don’t work with Lubuntu and my Acer laptop. Luckily, there is a command line solution for that:

xrandr --output LVDS1 --brightness 0.8

I’m pretty sure you can figure out that 0.8 means 80% right? Rest is simple 😀

I know that this is not a remarkable blog post but next time I’ll be sitting in the darkness blinded by my screen’s too strong brightness I’ll know exactly where to look for the command that changes it 🙂

Have a nice weekend!

Play Framework and the problem with anorm executeInsert and multiple rows

I’m using Play Framework 2.0 for a few of my projects and I find it amazing. Lately I had a little problem with the executeInsert() method of Anorm. This method, executes the query and returns an Option[Long] which is the id of the inserted row. That’s all fine when you do single row inserts but what happens when you do multiple row insert?

Well .. I was getting this error:

 Execution exception[[RuntimeException: SqlMappingError(too many rows when expecting a single one)]]

This was a bit of a problem because the alternative methods (execute() and executeUpdate()) provided by the framework also didn’t return what I wanted (the ids of the new rows).

So what should I do? I decided to dive into the code of Anorm and see what’s going on. I opened the Anorm.scala on GitHub and found the code of executeInsert (link to that line of code). Immediately after I read the implementation I realised that the method was taking an implicit parameter, which happened to be the result parser that collects the inserted row ids. And that parser was by default set to scalar[Long].singleOpt.

So the solution to my problem was very simple! I just had to provide another parser as a parameter that would return me all the rows. Can you guess what would that be?

.executeInsert( scalar[Long] * )

Hope this blog post will be useful to somebody else in the future 🙂 .. that’s why I’m writing it anyway!

Have a nice day!!

Pay attention on the details. It matters!

I watched by accident yesterday this TED talk by Rory Sutherland and it changed (at least for now) my view of the “small stuff” or the details. As a developer doing IT consulting as daily job I have hundreds of little tasks on my todo list which I don’t like doing. Some of them are really small changes, like changing the font size somewhere etc, but I never have the appetite to d them. I just find them boring & while there are more “important” things to do I never find time to do any of them.

But yesterday after watching this talk I got inspired and I did some improvements on a data dashboard. Those were small stuff like making the table header scroll down so you it’s always visible or changing the display of dates from “2012-10-25” to “Mon 25/10”.

And you know what? It worked! Today at noon I got this email (see below).

The changes you have made to the dashboard for the data checking is AWESOME!!!!!!

Super Thank you!!!!! :-)

This has of course brought a big smile on my face and a lot of motivation to do more things. Some of them are other small stuff that I would never do.

Enjoy the talk! which very probably you’ll find completely irrelevant to what I wrote above but it worked for me so I want to share it with you 🙂

Multiple editing with Sublime Text 2

There are many times where you want to rename a variable that appears in many lines right? How can you do that with Sublime Text 2?

Alt + F3 <while having the cursor on what you want to rename>

Also, if Alt + F3 selects too many variables you can use to select them one by one (selects the next appearance each time you press it)

Ctrl + D <again while having the cursor on what you want to rename>

I know it’s really simple shortcut & you might be wondering why did I even post about it. Well .. the reason is that I simply forget it every time and I thought of writing it here so I know where to find it when I need it. Cause apparently I’m searching with the wrong keywords (multiple line editing in Sublime Text 2) and I don’t get the quick answer I need.

Hope this will be useful to somebody else as well 🙂

Update: Found this nice about the multiple selection keyboard shortcuts for Sublime Text 2

Have a nice day!

Alt + Shift + 0 on DWM

I have been using DWM for more than a year & I certainly love this window manager. It’s so lightweight, fast & simple that makes you forget all the features it is missing.

What I discovered today by accident is that you can attach a window to all the tags! Guess how?

Alt + Shift + 0 of course!

Why would that be useful? Well .. for me it’s useful cause I want sometimes to have the browser in all the tags so I can see it when I am looking at the code or when I’m doing some database changes on the terminal. Other reason could be to have an active skype chat all around so that you notice when a person replied.

If you don’t find it useful then you can not use it of course. But I won’t tell you the command how to remove it from all tags 🙂

Functional Programming in PHP

For the last half a year I have been coding in Scala and today I had to switch back to PHP to add some functionality to an old service. The interesting part was that it was coming more naturally to me to use filter and map to do my job instead of using foreach. Well .. here is what came out:


$keywords = array_filter( explode(" ",$keyword), function($x) { return !empty($x); } );
$keywordsQuery = implode( " AND ", array_map ( function($x) { return "body LIKE '%$x%'"; }, $keywords) );

This was the first time I was using array_filter and array_map and anonymous functions so I was very excited while writing it but the result isn’t the most readable. Also it wasn’t so easy to write it cause I had to go to the PHP website to check in which order do the arguments go (first the callback or the array?), which is something you don’t need to check when coding in a more object-oriented way. Also I noticed that PHP’s anonymous functions have a similar ugliness with Javascript. You have to write the whole word “function” which takes quite some space and makes inline anonymous functions very verbose & hard to read.

Anyway. Luckily I wont have to write too much code in PHP for this new feature and I hope there wont be many more things to write in PHP. I’m not saying that the there is something wrong with the language. I’m just saying it’s hard to go back from Scala to PHP.

So .. that’s all I wanted to share with you today. Below is the code of how I would do it in Scala (didn’t run it but more or less it should work!).


keywords = keyword.split(" ").filter(_.nonEmpty).map(x => "body LIKE '%" + x + "%'").mkString(" AND ")