Routes with optional parameter - Play 2.1 Scala

前端 未结 5 923
旧巷少年郎
旧巷少年郎 2020-12-10 03:20

So in Play 2.0 I had this:

GET     /tasks/add              controllers.Tasks.addTask(parentId: Option[Long] = None)
GET     /tasks/:parentId/add    controlle         


        
相关标签:
5条回答
  • 2020-12-10 03:59

    Play 2.0 supported Option in path parameters, Play 2.1 no longer supports this, they removed the PathBindable for Option.

    One possible solution would be:

    package extensions
    import play.api.mvc._
    object Binders {
      implicit def OptionBindable[T : PathBindable] = new PathBindable[Option[T]] {
        def bind(key: String, value: String): Either[String, Option[T]] =
          implicitly[PathBindable[T]].
            bind(key, value).
            fold(
              left => Left(left),
              right => Right(Some(right))
            )
    
        def unbind(key: String, value: Option[T]): String = value map (_.toString) getOrElse ""
      }
    }
    

    And add this to Build.scala using routesImport += "extensions.Binders._". Run play clean ~run and it should work. Reloading the Binders on the fly only sometimes works.

    0 讨论(0)
  • 2020-12-10 04:06

    I had the same thing and more if you specify the pass as GET/foo:id and controllers.Application.foo(id : Option[Long] ?= None) you get an error It is not allowed to specify a fixed or default value for parameter: 'id' extracted from the path on the other side you can do as follows GET/foo controllers.Application.foo(id : Option[Long] ?= None) and it will work expecting that your request looks like as .../foo?id=1

    0 讨论(0)
  • 2020-12-10 04:09

    I think you have to add a question mark:

    controllers.Tasks.addTask(parentId: Option[Long] ?= None)

    0 讨论(0)
  • 2020-12-10 04:09

    From this routes-with-optional-parameter the suggestion goes like:

    GET   /                     controllers.Application.show(page = "home")
    GET   /:page                controllers.Application.show(page)
    
    0 讨论(0)
  • 2020-12-10 04:18

    The simple solution to your problem, without having to pass a default value, is to add a simple proxy method that wraps the parameter in an option.

    Routes:

    GET     /tasks/add              controllers.Tasks.addTask()
    GET     /tasks/:parentId/add    controllers.Tasks.addTaskProxy(parentId: Long)
    

    Controller:

    def addTask(parentId: Option[Long] = None) = Action { 
        Ok(views.html.addTask(taskForm, parentId))  
    }
    
    def addTaskProxy(parentId: Long) = addTask(Some(parentId))
    
    0 讨论(0)
提交回复
热议问题