Scala / Play:访问模型中的当前URL

时间:2013-11-21 12:25:49

标签: scala playframework playframework-2.0

我有一个简单的Play应用程序,我需要检查被调用的url并相应地使用不同的数据库。我知道在控制器中访问当前URL很容易,但为了实现这一点,我需要在模型中访问它。

将控制器中的URL传递给模型方法的每次调用都会带来太大的不便。有没有其他方法可以解决这个问题?

Play Framework 2.2.1 / Scala 2.10.3

更新:这是我的基本示例

控制器(Application.scala):

package controllers

import play.api._
import play.api.mvc._

import models.Data

object Application extends Controller {

    def index = Action {
        //Call to model method - model should somehow get the URL without it being passed as a param        
        val smth: String = Data.getSmth()
        Ok(smth);
    }

}

模型(Data.scala):

package models

object Data {

    def getSmth: Option[String] = DB.withSession {
        val db = //this is where I need the url to decide which database to use
        sql"""SELECT #$db.smth FROM smthTable""".as[String].firstOption
    }

}

1 个答案:

答案 0 :(得分:1)

所以,这是Play Scala API中的设计 - 没有神奇的上下文,如果你想要数据,你必须将它传递给你需要它的任何代码。

您必须将网址作为某种参数,您可以这样做:

case class MyModel(someData: String, requestUrl: String)

object MyModel {
  def apply(someData: String, request: Request) = 
    new MyModel(someData, request.url)
}

这可以清楚地表达依赖关系,但是在您的特定应用程序中,您可以从每个请求中调用它,并且希望避免重复提供该参数,在这种情况下,您可以使用Scala implicits,这会使编译器查找匹配的隐式在当前范围内具有相同类型的实例(您可以在此处阅读更多相关信息:http://www.scala-lang.org/old/node/114)。

object MyModel {
  def apply(someData: String)(implicit request: Request) = 
    new MyModel(someData, request.url)
}

然后可以从像这样的控制器动作中调用

def myAction = Action { implicit request => 
  val model = MyModel("blablabla")
  ...
}

当然,将模型与Play API紧密结合可能是一个坏主意,你可能应该引入自己的类来表示这个'上下文',然后你可以隐式地从Request转换为{{ 1}}在您的控制器中,让模型隐式使用YourContext

如果所有这些听起来像是胡言乱语,那么在尝试在Scala中构建Web应用程序之前,您应该从实际学习Scala开始。现在有很多好书(例如“Scala for the impatient”)以及众多优秀的在线资源(the neophytes guide to scala是好的)。

祝你好运!