bertzzie
bertzzie

Reputation: 3568

Handling Error on Insert PlayFramework 2.0 Scala

I'm having problem inserting (or updating) new data to database using anorm in Play Framework 2.0. My model is a blog post defined in the following code:

case class Post(title: String,
    content: String,
    created: String,
    lastUpdate: String,
    writer: Long,
    id: Long = 0)

Then I do this on the insert function:

def create(title: String, content: String, userId: Long) = {
  DB.withConnection { implicit connection =>
    SQL("INSERT INTO post (title, content, created, writer) VALUES ({title}, {content}, NOW(), {writer})")
        .on(
          'title -> title,
          'content -> content,
          'writer -> userId).executeUpdate()
}

And the form:

val postForm = Form(
  tuple(
    "title" -> nonEmptyText,
    "content" -> nonEmptyText))

I did not have a userId field in the form because I don't trust the user's input on their own id. I get it from session. Anyway, that's why I can't directly put the validation code in postForm's declaration (because I think I can't access session both from the form and from model). And here's when it becomes ugly. If the post is invalid, anorm throws an Exception so I need to pass the error to user AFTER the fold function like:

postForm.bindFromRequest.fold(
  formWithErrors => BadRequest(views.html.post.newPost(formWithErrors)),
    newPost => {
      try {
        val userId = request.session.get("id").getOrElse("0")
        models.Post.create(newPost._1, newPost._2, userId.toLong)
      } catch {
        case e => BadRequest(views.html.post.newPost(postForm.fill(newPost)))
      }
    Redirect(routes.Application.index)
})

First, the try-catch is ugly. Second, the BadRequest call don't work. What am I doing wrong? What is the best way to handle errors in insert / update? I have the same problem with a login form, but it's not as bad as this because I can actually handle errors at login form declaration.

Thanks before.

Upvotes: 2

Views: 1546

Answers (1)

Jean
Jean

Reputation: 21595

Assuming the error is on an integrity constraint like 0 not existing in the database, what about something like this ?

    postForm.bindFromRequest.fold(   
        formWithErrors => BadRequest(views.html.post.newPost(formWithErrors)),
        newPost => {
            request.session.get("id").map({ userId=> 
               models.Post.create(newPost._1, newPost._2, userId.toLong)       
               Redirect(routes.Application.index) 
            }).getOrElse{
                BadRequest(views.html.post.newPost(postForm.fill(newPost))) 
            }
        }   
    )

You don't give invalid information to anorm and don't get an error ...

ps : I don't have a scala compiler on hand to check the syntax right now, I might have missed a paren or mixed a paren with a curly :)

Upvotes: 1

Related Questions