2015-10-05 93 views
3

我刚从Play框架和Scala开始。如何使用Play与Scala和Slick从数据库获取记录

要习惯它,我开发一个歌词web应用程序,但我有一些麻烦,虽然从数据库中获取记录...

下面是我MusicController.scala。我在def show(id: Long)处遇到错误。我修改了我发现的代码here

enter image description here

我想我需要实现findById(id),对不对?但是哪里?如何?

最近我一直在使用Laravel,我发现找到Play with Scala资源和代码示例要困难得多。在这种情况下,文档具有我需要的内容,但我在黑暗中关于在何处以及如何实施findById(id)。我错过了什么吗?

Music.scala

package models 

import play.api.libs.json.Json 

case class Music(id: Long, title: String, lyrics: String, year: Int) 

object Music { 
    implicit val musicFormat = Json.format[Music] 
} 

MusicController.scala

package controllers 

import javax.inject.Inject 

import dal.MusicRepository 
import models.Music 
import play.api.data.Form 
import play.api.data.Forms._ 
import play.api.data.validation.Constraints._ 
import play.api.i18n.{I18nSupport, MessagesApi} 
import play.api.libs.json.Json 
import play.api.mvc._ 

import scala.concurrent.{Future, ExecutionContext} 

class MusicController @Inject()(repo: MusicRepository, val messagesApi: MessagesApi) 
           (implicit ec: ExecutionContext) extends Controller with I18nSupport { 

    def index = Action { 
    Ok(views.html.musics.index(musicForm)) 
    } 

    def show(id: Long) = Action { 
    Music.findById(id).map { music => 
     Ok(views.html.musics.show(music)) 
    }.getOrElse(NotFound) 
    } 

    val musicForm: Form[CreateMusicForm] = Form { 
    mapping(
     "title" -> nonEmptyText, 
     "lyrics" -> nonEmptyText, 
     "year" -> number.verifying(min(0)) 
    )(CreateMusicForm.apply)(CreateMusicForm.unapply) 
    } 

    def addMusic = Action.async { implicit request => 
    musicForm.bindFromRequest.fold(
     errorForm => { 
     Future.successful(Ok(views.html.musics.index(errorForm))) 
     }, 
     music => { 
     repo.create(music.title, music.lyrics, music.year).map { _ => 
      Redirect(routes.MusicController.index) 
     } 
     } 
    ) 
    } 

    def getMusics = Action.async { 
    repo.list().map { musics => 
     Ok(Json.toJson(musics)) 
    } 
    } 

} 

case class CreateMusicForm(title: String, lyrics: String, year: Int) 

MusicRepository.scala

package dal 

import javax.inject.Inject 

import models.Music 
import play.api.db.slick.DatabaseConfigProvider 
import slick.driver.JdbcProfile 

import scala.concurrent.{Future, ExecutionContext} 

class MusicRepository @Inject()(dbConfigProvider: DatabaseConfigProvider) 
           (implicit ec: ExecutionContext) { 

    private val dbConfig = dbConfigProvider.get[JdbcProfile] 

    import dbConfig._ 
    import driver.api._ 

    private class MusicsTable(tag: Tag) extends Table[Music](tag, "musics") { 
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc) 

    def title = column[String]("title") 

    def lyrics = column[String]("lyrics") 

    def year = column[Int]("year") 

    def * = (id, title, lyrics, year) <>((Music.apply _).tupled, Music.unapply) 
    } 

    private val musics = TableQuery[MusicsTable] 

    def create(title: String, lyrics: String, year: Int): Future[Music] = db.run { 
    (musics.map(m => (m.title, m.lyrics, m.year)) 
     returning musics.map(_.id) 

     into ((stuff, id) => Music(id, stuff._1, stuff._2, stuff._3)) 

    ) +=(title, lyrics, year) 
    } 

    def list(): Future[Seq[Music]] = db.run { 
    musics.result 
    } 

} 

提前谢谢!

+0

由于错误提示,你可能想实现' findById'作为'Music'对象中的一个方法。虽然它听起来像是属于MusicRepository,但它最有可能从DB获取记录... –

+0

感谢您的帮助。你是正确的,我已经设法做我正在寻找的东西:)现在发布答案 –

回答

1

我设法解决同样它:

MusicController.scala

def show(id: Long) = Action.async { implicit request => 
    repo.findById(id).map { music => 
     Ok(views.html.musics.show(music)) 
    } 
    } 

MusicRepository.scala

def findById(id: Long): Future[Music] = db.run { 
    musics.filter(_.id === id).result.head 
    } 
相关问题