3

I am creating a backend API with Play Framework and Scala. I would like to map the incoming request to a scala object. One of the instance variables of the object is a list of channels. Here is what I currently have:

Controller method that takes the request and attempts to map it to a user:

def addUser = Action(parse.json) { request =>
  request.body.validate[User].fold({ errors =>
    BadRequest(Json.obj(
      "status" -> "Error",
      "message" -> "Bad JSON",
      "details" -> JsError.toFlatJson(errors)
    ))
  }, { user =>
    User.create(user.pushToken, user.channels)
    Ok(Json.obj("status" -> "OK", "message" -> "User created"))
  })
}

User case class:

case class User(id: Pk[Long], pushToken: String, channels: List[String])

User formatter:

implicit val userFormat = (
  (__ \ "id").formatNullable[Long] and
  (__ \ "pushToken").format[String] and
  (__ \ "channels").format[List[String]]
  )((id, pushToken, channels) => User(id.map(Id(_)).getOrElse(NotAssigned), pushToken, channels),
  (u: User) => (u.id.toOption, u.pushToken, u.channels))

User anorm create method:

def create(pushToken: String, channels: List[String]) {
  DB.withConnection { implicit c =>
    SQL("insert into user (pushToken, channels) values ({pushToken}, {channels})").on(
      'pushToken -> pushToken,
      'channels -> channels
    ).executeUpdate()
  }
}

When I try to compile, I get:

Compilation error[could not find implicit value for parameter extractor: anorm.Column[List[String]]]

Ideally, I would like to be able to accept this as a user:

{
  "pushToken":"4jkf-fdsja93-fjdska34",
  "channels": [
    "channelA", "channelB", "channelC"
  ]
}

and create a user from it.

eliot
  • 1,319
  • 1
  • 14
  • 33
  • Which DBMS? What does your schema look like? The error message is saying anorm doesn't know how to map a list to a database field, I think. – Robin Green Nov 10 '13 at 16:50
  • @RobinGreen I'm still very early in the development process for this and am using the in-memory, default database. I guess that would also be part of my question. Do I have to have a different database table that maps channels to users? In Play 1, I could just make the database field a byte array and JPA would map the rest for me. – eliot Nov 11 '13 at 13:28
  • Yes, I would say you're going to need a separate table for channel to user mappings. If you wanted to store it in a byte array then you would probably have to change `(__ \ "channels").format[List[String]]`. – Akos Krivachy Nov 12 '13 at 01:19

1 Answers1

-1

You can't use List[String] as column value in Anorm, thats the problem

You should use mkString method or smth else

Lucky Libora
  • 140
  • 1
  • 3