带有可选参数的路径 - 播放2.1 Scala

时间:2013-02-20 13:23:49

标签: scala playframework-2.0 playframework-2.1

所以在Play 2.0中我有这个:

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

使用这样的控制器方法:

def addTask(parentId: Option[Long]) = Action { 
    Ok(views.html.addTask(taskForm, parentId))  
}

它正在发挥作用。当我迁移到2.1时,它似乎抱怨这些行:No URL path binder found for type Option[Long]. Try to implement an implicit PathBindable for this type.基本上,我想要完成的是将路由tasks/add和路由tasks/123/add链接到相同的方法接受Optional[Long]。知道怎么做吗?感谢。

好的,所以我得到了一种不是bug,它是Lighthouse上的一个功能响应:“我们删除了路径绑定中的Option [Long]支持,因为拥有可选路径参数没有意义。你可以如果你愿意,可以实现你自己的路径可绑定支持它。“到目前为止,我有2个解决方案,传递-1作为parentId,我不太喜欢。或者有两种不同的方法,在这种情况下可能更有意义。实现PathBindable现在似乎不太可行,所以我可能会坚持使用2种方法。

5 个答案:

答案 0 :(得分:14)

播放2.0支持Option路径参数,Play 2.1不再支持此功能,他们删除了选项的PathBindable。

一种可能的解决方案是:

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 ""
  }
}

使用Build.scala将其添加到routesImport += "extensions.Binders._"。运行play clean ~run,它应该工作。只在运行中重新加载粘合剂有时会起作用。

答案 1 :(得分:7)

我认为你必须添加一个问号:

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

答案 2 :(得分:5)

routes-with-optional-parameter开始,建议如下:

GET   /                     controllers.Application.show(page = "home")
GET   /:page                controllers.Application.show(page)

答案 3 :(得分:2)

您的问题的简单解决方案,无需传递默认值,就是添加一个简单的代理方法,将参数包装在一个选项中。

路线:

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

控制器:

def addTask(parentId: Option[Long] = None) = Action { 
    Ok(views.html.addTask(taskForm, parentId))  
}

def addTaskProxy(parentId: Long) = addTask(Some(parentId))

答案 4 :(得分:0)

我有同样的事情,如果您将通行证指定为GET/foo:idcontrollers.Application.foo(id : Option[Long] ?= None)您会在另一方面收到错误It is not allowed to specify a fixed or default value for parameter: 'id' extracted from the path,您可以执行以下操作GET/foo controllers.Application.foo(id : Option[Long] ?= None)并且可以预期您的请求看起来像.../foo?id=1

相关问题