如何使用Scala重定向到play框架中的相同控制器方法?

时间:2011-10-25 05:39:34

标签: scala playframework

打开网址时

/users/{id}/foo

我将通过调用

来显示视图
html.foo(userWithId)

在控制器方法foo中,我想确保id与loggedin用户的id相同,如果不是,则应将用户重定向到

/users/{theLoggedInUsersId}/foo

使用

html.foo(loggedInUser)

工作正常,但这不是重定向,因此浏览器中的网址仍为

/users/{id}/foo

我想真正重定向,以便网址显示正确的ID。我不知道该怎么做。像这样使用“动作”:

Action(foo(loggedInUsersId))

将在不提供返回类型的情况下使用递归时出错。将返回类型play.template.Html添加到控制器方法foo,将得到编译器错误,因为Action返回ScalaAction而不是Html。

我该怎么办?我是否应该这样做,我是不是以错误的方式思考它?

修改

重定向(...)工作正常。但是没有它可能吗? 在伪Scala中:

def list(id: Long) = {
  if (some_criteria)
    html.list(user_with_id_equal_to_id)
  else if(another_criteria)
    list(another_user_id)
  else
    Action(Application.login)
}

列表(another_user_id)不起作用,因为它是一个递归调用,我必须在list方法上提供一个返回类型。添加返回类型 play.templates.Html 将不起作用,因为它不是 Action 的返回类型

你看到我得到了什么吗?如果我不使用对 list 的调用使用html.list(user_with_another_id),那么它将不是重定向,浏览器中的url仍然是/ users / id / foo而不是/ user / another_id / foo中。

1 个答案:

答案 0 :(得分:5)

有两种方法可以做到这一点。第一种是使用Redirect返回类型。

Redirect("/find/user/" + id)

您想要的方式是使用您建议的操作。

Action(findUser(id))

这应该可以正常工作。 Play实际上将此调用解析为URL并调用重定向。所以我向你展示的第一个例子几乎是一样的。 Action更好用,因为它可以防止您在更改URL时更改代码。我们可能需要查看更多代码才能看到正在发生的事情。

这是一个更清晰的例子。

    def index( userId : Option[ String ] ) = {  

    Action(findCurrentUser(userId.getOrElse("test@test.com")))
}

def findCurrentUser(userId : String) = {

    User.find( "email = {email}" ).onParams( userId ).first() match {

        case Some( user ) => Json( user )

        case None => Error( "Could not find current user" )
    }
}

参考:http://scala.playframework.org/documentation/scala-0.9.1/controllers#Returntypeinference