play framework with scalate and activerecord

WRYYYYYYYYYYYYYYYY

Dio Brando on Scala crazy dependencies

Scala works like CSS selectors in that every successor overrides its predecessor.

You will have to work as a detective to figure out the correct recipe to manage a huge casserole of hodgepodge.

To achieve a working Play configuration with scalate and activerecord needs:

In build.sbt:

1
2
3
4
5
6
7
8
9
scalaVersion := "2.10.3"
libraryDenpendencies ++= Seq(
jdbc,
"org.scalatra.scalate" %% "scalate-core" % "1.7.0",
"com.github.aselab" %% "scala-activerecord" % "0.2.3",
"com.github.aselab" %% "scala-activerecord-play2" % "0.2.3",
"com.h2database" % "h2" % "1.3.170"
)

Several notes:

  1. Currently scala-activerecord only supports 2.10.3
  2. scalate must be 1.7.0+ for better support on scala 2.10 but the current stable version is 1.6.0

Then in the root path of play project, create a new file located at app/lib/ScalateIntegration.scala

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package controllers
import play.api._
import http.{Writeable, ContentTypeOf, ContentTypes}
import mvc.Codec
import play.api.Play.current
import org.fusesource.scalate.layout.DefaultLayoutStrategy
import collection.JavaConversions._
object Scalate {
import org.fusesource.scalate._
import org.fusesource.scalate.util._
var format = Play.configuration.getString("scalate.format") match {
case Some(configuredFormat) => configuredFormat
case _ => "scaml"
}
lazy val scalateEngine = {
val engine = new TemplateEngine
engine.resourceLoader = new FileResourceLoader(Some(Play.getFile("app/views")))
engine.layoutStrategy = new DefaultLayoutStrategy(engine, "app/views/layouts/default." + format)
engine.classpath = "tmp/classes"
engine.workingDirectory = Play.getFile("tmp")
engine.combinedClassPath = true
engine.classLoader = Play.classloader
engine
}
def apply(template: String) = Template(template)
case class Template(name: String) {
def render(args: java.util.Map[String, Any]) = {
ScalateContent{
scalateEngine.layout(name, args.map {
case (k, v) => k -> v
} toMap)
}
}
}
case class ScalateContent(val cont: String)
implicit def writeableOf_ScalateContent(implicit codec: Codec): Writeable[ScalateContent] = {
Writeable[ScalateContent]((scalate:ScalateContent) => codec.encode(scalate.cont))
}
implicit def contentTypeOf_ScalateContent(implicit codec: Codec): ContentTypeOf[ScalateContent] = {
ContentTypeOf[ScalateContent](Some(ContentTypes.HTML))
}
}

Again only works on scalate 1.6.

Finally, according to activerecord‘s doc.
To load the plugin, in conf/play.plugin

1
9999:com.github.aselab.activerecord.ActiveRecordPlugin

To configure database, in conf/application.conf

1
2
3
4
5
6
7
8
9
10
11
12
# Database configuration
# ~~~~~
#
# Scala ActiveRecord configurations
db.activerecord.driver=org.h2.Driver
db.activerecord.url="jdbc:h2:mem:play"
db.activerecord.user="sa"
db.activerecord.password=""
# Schema definition class
activerecord.schema=models.Tables

And in app/models/person.scala

1
2
3
4
5
6
7
package models
import com.github.aselab.activerecord._
import com.github.aselab.activerecord.dsl._
case class Person(@Required name: String) extends ActiveRecord
object Person extends ActiveRecordCompanion[Person] with PlayFormSupport[Person]

In app/models/tabels.scala

1
2
3
4
5
6
7
8
package models
import com.github.aselab.activerecord._
import com.github.aselab.activerecord.dsl._
object Tables extends ActiveRecordTables with PlaySupport {
val models = table[Person]
}

And finally you can try this in console

1
2
3
4
5
6
7
8
9
activator console
import models._
import play.core.StaticApplication
new StaticApplication(new java.io.File("."))
Person("f@ck").save
Person.findBy("name", "f@ck")

WTF have I done? I just typed mechanically what I have ferreted on Google and StackOverflow.
WTF is play.core.StaticApplication that is just one confusing page on the doc?
Speciously tantializing is the magical code under which lurk complicated dependencies.

Reference: PlayframeWork Quick Tip