Play framework ã® Tutorial ã Scala 㨠Scalate ã§è¡ã(Step1, Step2)
Scala ã使ãå§ã㦠Java æå*1ã«è¾æãã¦ããæ¹ã¯çµ¶å¯¾ã«ä½¿ã£ãæ¹ãè¯ã Play framework ã® Tutorial ãè¡ã£ã¦ã¿ãã®ã§ããã®ã¡ã¢ãæ®ããPlay framework ã¯ã1.1 ã® beta version ãã¤ã³ã¹ãã¼ã«æ¸ã¿ã§ããã¨ä»®å®ããã
Tutorial ãå§ããåã®ä¸æºå
Play framework 㧠Scala 㨠Scalate ã使ãããã«ã¢ã¸ã¥ã¼ã«ãã¤ã³ã¹ãã¼ã«ããã
% sudo play install scala % sudo play install scalate
OSX ç°å¢ã§ä¸è¨ã®ã¨ã©ã¼ãåºãå ´åã¯ãç°å¢è¨å®ãã Proxy ãå¤ããªã©ã§å¯¾å¦ã10.5 ãã 10.6 ã¸æ´æ°ãã MBP ã§ã¯åºãªããã10.6 ãå§ãããå ¥ã£ã¦ãã Macmini ã§ã¯åºãã
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib.py", line 1425, in proxy_bypass_macosx_sysconf mask = int(m.group(2)[1:])
ã¡ãªã¿ã« play ã³ãã³ã㯠Java ã§ã¯ãªã Python ã§è¨è¿°ããã¦ããã®ã§ãã¨ã¦ã軽快ãééç´ã® sbt ãã解æ¾ãããã®ã§å¹¸ãã
Starting up the project (Scala version)
http://www.playframework.org/documentation/1.1-trunk/scguide1
Tutorial ã®éãã«è¡ã㨠scalate ã使ãããªãã®ã§ä¸è¨ã®ããã«ããã
% play new yabe --with scala,scalate
ãã®å¾ãapp/controllers.scala ã® Application ãªãã¸ã§ã¯ããç¶æ¿ãã¦ãã Controller ã ScalateController ã«å¤æ´ããããããæ ã㨠Controller ã® render ã¡ã½ãããå®è¡ãã index.html ãåå¨ããªãã¨æããããä»å㯠scalate ã使ãããã®ã§ index.ssp ãèªã¿è¾¼ãã§æ¬²ããã
//..snip.. object Application extends ScalateController { //..snip..
å¾ã¯ãTutorial ã®éãã«é²ããã ãã
A first iteration for the data model (Scala version)
http://www.playframework.org/documentation/1.1-trunk/scguide2
User ã¢ãã«ã¨ãã¹ãã®ä½æã§å¹¾ã¤ãã³ã³ãã¤ã«ã¨ã©ã¼ã«ãªãç®æãããããããã®ä¿®æ£ãè¡ãå¿ è¦ãããã
createAndRetrieveUser
app/models/User.scala ã®ä¸è¨ã¯åé¤ã
import javax.persistence._
ã¾ããå¾ã« Users ãªãã¸ã§ã¯ãã® find ã¡ã½ããã使ãã®ã§ app/models/User.scala ã«ã¯ä¸è¨ã追å ãã¦ããã
object Users extends QueryOn[User]
test/BasicTest.scala ã®ä¸è¨ã®è¡ãâ¦
val bob = find[User]("byEmail", "[email protected]").first
ä¸è¨ã®ããã«ä¿®æ£ããã
var bob = Users.find("byEmail", "[email protected]").first
Users.find ã®æ»ãå¤ã¯ Option ã¯ã©ã¹(ãã㯠Some ã None)ã§ãããããä¸è¨ãâ¦
assertEquals("Bob", bob.fullname)
ä¸è¨ã«å¤æ´ããå¿ è¦ãããã
assertEquals("Bob", bob.get.fullname)
tryConnectAsUser
app/models/User.scala ã§ä¸è¨ãã¤ã³ãã¼ãã User ãªãã¸ã§ã¯ããä½æããããæ示ãããããããã¯ç¡è¦ã
import play.db.jpa.QueryFunctions._
åè¿°ã§è¿½å ãã Users ãªãã¸ã§ã¯ãã« connect ã¡ã½ããã追å ããã
object Users extends QueryOn[User] { def connect(email: String, password: String) = { find("byEmailAndPassword", email, password).first } }
test/BasicTest.scala ã® tryConnectAsUser ã¯ä¸è¨ã®ããã«ãããassertNotEquals ã¨ã欲ãããªãã
@Test def tryConnectAsUser() { // Create a new user and save it new User("[email protected]", "secret", "Bob").save() // Test assertEquals("Bob", Users.connect("[email protected]", "secret").get.fullname) assertEquals(None, Users.connect("[email protected]", "badpassword")) assertEquals(None, Users.connect("[email protected]", "secret")) }
ScalaTest
ããã¾ã§æ¸ãã¦ãPlay Scala Module ã® Yabe ãµã³ãã«ã ScalaTest ã§ããäºã«æ°ãã¤ããtest/BasicTest.scala ãä¸è¨ã®ããã«ããã
import play.test._ import models._ import org.scalatest.matchers.ShouldMatchers class BasicTest extends UnitFlatSpec with ShouldMatchers { it should "create and retrieve a user" in { // Create a new user and save it new User("[email protected]", "secret", "Bob").save() // Retrieve the user with bob username var bob = Users.find("byEmail", "[email protected]").first // Test bob should not be (None) "Bob" should equal (bob.get.fullname) } it should "call connect on User" in { // Create a new user and save it new User("[email protected]", "secret", "Bob").save() // Test Users.connect("[email protected]", "secret") should not be (None) Users.connect("[email protected]", "badpassword") should be (None) Users.connect("[email protected]", "secret") should be (None) } }
ãã£ã¡ã®æ¹ããNone ãå¦ãããããªãã¦ã¦è¯ãã
createPost
app/models/Post.scala ã¯ãapp/models/User.scala åæ§ã« import ãåé¤ããä¸è¨ã®ãã㪠Posts ãªãã¸ã§ã¯ãã追å ãã¦ãããä»ã¯ Tutorial ã®ã¾ã¾ã§è¯ãã
object Posts extends QueryOn[Post]
追å ã§å人çãªè¶£å³ã§ãimport java.util._ãã§ã¯ãªããimport java.util.Dateãã¨ããã
ScalaTest ã«åãæ¿ããã®ã§ test/BasicTest.scala ã® Fixtures.deleteAll() ã®ç®æã¯ä¸è¨ã®ããã«ããã
//..snip.. import org.scalatest.BeforeAndAfterEach //..snip.. class BasicTest extends UnitFlatSpec with ShouldMatchers with BeforeAndAfterEach { override def beforeEach() { Fixtures.deleteAll() }
beforeEach ã¯ãorg.scalatest.BeforeAndAfterEach ã®ã¡ã½ããã§ããããå¿ããã«ç¶æ¿ãã¦ããã
ãã¹ãã±ã¼ã¹ã¯ä¸è¨ã®éãã
it should "create Post" in { // Create a new user and save it var bob = new User("[email protected]", "secret", "Bob").save() // Create a new post new Post(bob, "My first post", "Hello world").save() // Test that the post has been created 1 should equal (Posts.count()) // Retrieve all post created by bob var bobPosts = Posts.find("byAuthor", bob).fetch // Tests 1 should equal (bobPosts.size) var firstPost = bobPosts(0) firstPost should not be (null) bob should equal (firstPost.author) "My first post" should equal (firstPost.title) "Hello world" should equal (firstPost.content) firstPost.postedAt should not be (null) }
postComments
app/models/Comment.scala ã¯ä»ã®ã¢ãã«ã¨æ³¨æç¹ãåãã§ãããã説æçç¥ãComments ãªãã¸ã§ã¯ãã®è¿½å ã ãã¯å¿ããã«ã
ãã¹ãã±ã¼ã¹ã¯ä¸è¨ã®éãã
it should "post Comments" in { // Create a new user and save it var bob = new User("[email protected]", "secret", "Bob").save() // Create a new post var bobPost = new Post(bob, "My first post", "Hello world").save() // Post a first comment new Comment(bobPost, "Jeff", "Nice post").save() new Comment(bobPost, "Tom", "I knew that !").save() // Retrieve all comments var bobPostComments = Comments.find("byPost", bobPost).fetch // Tests 2 should equal (bobPostComments.size) var firstComment = bobPostComments(0) firstComment should not be (null) "Jeff" should equal ( firstComment.author) "Nice post" should equal ( firstComment.content) firstComment.postedAt should not be (null) var secondComment = bobPostComments(1) secondComment should not be (null) "Tom" should equal ( secondComment.author) "I knew that !" should equal (secondComment.content) secondComment.postedAt should not be (null) }
ããã§ãtmp ã®ä¸ã« Comment.class ãä½æãããã«ã¨ã©ã¼ãåºã¦ãã¾ã£ãã®ã§ãplay testããåå®è¡ãã¦ããã
useTheCommentsRelation
app/models/Post.scala ãä¸è¨ã®ããã«ä¿®æ£ããã
package models import java.util.{Date, List=>JList, ArrayList} import play.db.jpa._ @Entity class Post( @ManyToOne var author: User, var title: String, @Lob var content: String ) extends Model { var postedAt: Date = new Date() def this() = this(null, null, null) @OneToMany(mappedBy="post", cascade=Array(CascadeType.ALL)) var comments: JList[Comment] = new ArrayList[Comment] def addComment(author: String, content: String) = { val newComment = new Comment(this, author, content) newComment.save() comments.add(newComment) this } } object Posts extends QueryOn[Post]
ãã¹ãã±ã¼ã¹ã¯ä¸è¨ã®éãã
//..snip.. import scala.collection.JavaConversions._ //..snip.. it should "use the comments relation" in { // Create a new user and save it var bob = new User("[email protected]", "secret", "Bob").save() // Create a new post var bobPost = new Post(bob, "My first post", "Hello world").save() // Post a first comment bobPost.addComment("Jeff", "Nice post") bobPost.addComment("Tom", "I knew that !") // Count things 1 should equal (Users.count()) 1 should equal (Posts.count()) 2 should equal (Comments.count()) // Retrieve the bob post val getBobPost = Posts.find("byAuthor", bob).first getBobPost should not be (None) // Navigate to comments 2 should equal (getBobPost.get.comments.size) "Jeff" should equal (getBobPost.get.comments(0).author) // Delete the post getBobPost.get.delete() // Chech the all comments have been deleted 1 should equal (Users.count()) 0 should equal (Posts.count()) 0 should equal (Comments.count()) }
scala.collection.JavaConversions ã import ãã¦ãããªãã¨ãgetBobPost.get.comments(0)ãã®ç®æ㧠java.util.List ãããã®ã¾ã¾ä½¿ç¨ããã¦ãã¾ãã®ã§æ°ãã¤ããã
ããã¯ãModel å´ã§ã©ãã«ããããã®ã§ãå¾ã§èããã
fullTest
ãã¹ãã±ã¼ã¹ã¯ä¸è¨ã®éãã
it should "work if things combined together" in { Fixtures.load("data.yml") // Count things 2 should equal (Users.count()) 3 should equal (Posts.count()) 3 should equal (Comments.count()) // Try to connect as users Users.connect("[email protected]", "secret") should not be (None) Users.connect("[email protected]", "secret") should not be (None) Users.connect("[email protected]", "badpassword") should be (None) Users.connect("[email protected]", "secret") should be (None) // Find all bob posts var bobPosts = Posts.find("author.email", "[email protected]").fetch 2 should equal (bobPosts.size) // Find all comments related to bob posts var bobComments = Comments.find("post.author.email", "[email protected]").fetch 3 should equal (bobComments.size) // Find the most recent post var frontPost = Posts.find("order by postedAt desc").first frontPost should not be (None) "About the model layer" should equal (frontPost.get.title) // Check that this post has two comments 2 should equal (frontPost.get.comments.size) // Post a new comment frontPost.get.addComment("Jim", "Hello guys") 3 should equal (frontPost.get.comments.size) 4 should equal (Comments.count()) }