【问题标题】:Scala/Play: access current url in a modelScala/Play:访问模型中的当前 url
【发布时间】:2013-11-21 22:40:57
【问题描述】:

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

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

播放框架 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
    }

}

【问题讨论】:

  • 我认为无法访问模型中的当前 url。因为该模型与http无关。可能您可以在模型构造函数中定义一个隐式请求参数。但我不认为这是个好主意。
  • @jilen 如何在模型构造函数中定义该参数?我仍然需要通过它或以某种方式访问​​它。当然,这样的情况应该不少见吧?
  • case class Foo(val bar: Int, val baz: String) case object Foo { def apply(bar: Int)(implicit request: play.api.mvc.Request[_]) = new Foo(bar, request.path) } 这样的东西,这确实不是个好主意。
  • @jilen 我认为这不是我想要的。我必须说我很失望,这么明显且常见的问题在 Play 上没有解决方案。
  • 有,要么显式传递,要么隐式传递。

标签: scala playframework playframework-2.0


【解决方案1】:

因此,这是在 Play Scala API 中设计的 - 没有神奇的上下文,如果您需要数据,您必须将其传递给需要它的任何代码片段。

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

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

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

这将清楚地表达依赖关系,但在您的特定应用程序中,您可能会从每个请求中调用它,并希望避免重复提供该参数,在这种情况下,您可以使用 Scala 隐式,它使编译器寻找匹配的隐式在当前范围内具有相同类型的实例(您可以在此处阅读更多信息: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 Request API 紧密耦合可能是个坏主意,您可能应该引入自己的类来表示这个“上下文”,然后您可以从 Request 隐式转换为 YourContext in您的控制器并让模型隐式使用YourContext

如果所有这些对您来说都是胡言乱语,那么您可能应该先从实际学习 Scala 开始,然后再尝试在 Scala 中构建 Web 应用程序。现在有很多好书(例如'Scala for the impatient')以及大量好的在线资源(the neophytes guide to scala 是一个很好的资源)。

祝你好运!

【讨论】:

  • 我对 Scala 的了解足以拼凑出一个 CRUD 应用程序,但这仍然令人困惑。我已经用我自己的例子更新了我的问题,显然有几个空白是我问题的重点。
  • 好的,阅读您更新的问题我的答案仍然相同,除了将其作为参数传递之外,您不能以任何其他方式将数据传递给 scala 中的函数。
  • 很难相信 Play 不能做任何糟糕的 PHP MVC 框架可以做的事情。好吧,如果你说这不可能,我想这是不可能的。
  • Play 没有这样做,因为它打破了 MVC 范式。正如你所说,那些 PHP 框架很糟糕是有原因的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-27
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-09
相关资源
最近更新 更多