使用Scala问题方面发挥框架油滑会议(Problems with Scala Play Frame

2019-10-18 19:38发布

我创建使用播放2.2 Scala中的应用程序。 我使用的play-slick 0.5.0.8作为我的MySQL数据库连接。 我有以下应用控制器:

package controllers

import models._
import models.database._

import play.api._
import play.api.mvc._
import play.api.Play.current
import play.api.db.slick._

object Application extends Controller {
  // WORKS:
  def test = DBAction {
    implicit session => Ok(views.html.test(Cameras.findById(1)))
  }

  // DOES NOT WORK:
  def photo = Action {
    val p = PhotoFetcher.fetchRandomDisplayPhoto(someParametersBlah))
    Ok(views.html.photo(p))
  }
}

正如你所看到的, test DBAction的作品,它是能够获取从DB就好了一张照片。 不幸的是, photo行动不起作用。

PhotoFetcher.fetchRandomDisplayPhoto(blah)做了一堆不同的东西。 埋在它的内部是一个呼叫Cameras.findById(blah) ,这应返回Camera对象(在其中工程test DBAction)。 然而,这个配置我得到以下错误:

could not find implicit value for parameter s: slick.driver.MySQLDriver.simple.Session

我试图使photo行动统一到DBAction,就像这样:

def photo = DBAction {
  implicit session => {
    val p = PhotoFetcher.fetchRandomDisplayPhoto(someParametersBlah))
    Ok(views.html.photo(p))
  }
}

但是,这只是导致同样缺少会话错误。 这就像PhotoFetcher不知道隐含的会话。

其他的事情,我已经试过是进口slick.session.Database.threadLocalSessionPhotoFetcher ,但仅会导致以下错误:

SQLException: No implicit session available; threadLocalSession can only be used within a withSession block

如果它的任何帮助,这是我的一个简化版本, Cameras的对象:

package models.database

import models.Format.Format
import scala.slick.driver.MySQLDriver.simple._

case class Camera(id: Long,
                  otherStuff: String)

trait CamerasComponent {
  val Cameras: Cameras

  class Cameras extends Table[Camera]("cameras") {
    def id          = column[Long]("id", O.PrimaryKey, O.AutoInc)
    def otherStuff  = column[String]("otherStuff", O.NotNull)

    def * = id ~ otherStuff <> (Camera.apply _, Camera.unapply _)

    val byId         = createFinderBy(_.id)
    val byOtherStuff = createFinderBy(_.otherStuff)
  }
}

object Cameras extends DAO {
  def insert(camera: Camera)(implicit s: Session) { Cameras.insert(camera) }
  def findById(id: Long)(implicit s: Session): Option[Camera] = Cameras.byId(id).firstOption
  def findByOtherStuff(otherStuff: String)(implicit s: Session): Option[Camera] = Cameras.byOtherStuff(model).firstOption
}

所以,好像我已经得到了跨越式的地方。 现在它是唯一我能够直接从控制器DBAction访问我的DAO对象,而不是从一些不同类的内部。 任何帮助,将不胜感激。 谢谢!

Answer 1:

请问您的定义PhotoFetcher.fetchRandomDisplayPhoto.fetchRandomDisplayPhoto采取隐式会话?

 // PhotoFetcher
 def fetchRandomDisplayPhoto(args: Blah*)(implicit s: Session) = {
   // ...
   val maybeCam = Cameras.findById(blah) // <- sees the implicit session 
   // ...
 }

或者是你依靠threadLocalsessionPhotoFetcher ? (对于没有隐含会话参数fetchRandomDisplayPhoto )?

虽然油滑的threadLocalSession是方便快速地尝试的东西,它可以导致清晰度的混乱和损失以后。 它最好只使用显式(implicit s: Session)的参数列表中是否有打电话给你的油滑模型中的所有方法。 这也打得很好DBAction ,让框架管理会话。

缺点是你必须有(implicit s: Session)上所有的方法-有这样的解决方法: https://github.com/freekh/play-slick/issues/20

Scala是不详细,非常适合于重构-所以我建议想着那个桥过的,当你来到它,并用DBAction对于做数据库的东西的一切行动; 给调用您的数据库模型的隐含会话的所有方法,看看有多少是里程,给你。



文章来源: Problems with Scala Play Framework Slick Session