play vs rails

36
Play 2.0 Ruby On Rails X by @danicuki

Upload: daniel-cukier

Post on 15-Jan-2015

30.273 views

Category:

Technology


1 download

DESCRIPTION

Comparison between Play Framework (Scala) and RubyOnRails (Ruby)

TRANSCRIPT

Page 1: Play vs Rails

Play 2.0

RubyOn

RailsX

by @danicuki

Page 2: Play vs Rails

Documentationhttp://www.playframework.com/documentation/ http://guides.rubyonrails.org/

Page 3: Play vs Rails

Installing

$  apt-­‐get  install  ruby$  apt-­‐get  install  rubygems$  gem  install  rails

$ apt-get install java$ wget play-2.1.0.zip$ unzip play-2.1.0.zip$ export PATH=$PATH:/pathToPlay

http://www.playframework.com/documentation/2.1.0/Installing

Page 4: Play vs Rails

First App

$  rails  new  myapp$ play new myapp

Page 5: Play vs Rails

Project Structureapp/ ! assets ! stylesheets ! javascripts ! controllers ! models ! views conf/ ! application.conf ! routes public/ project ! build.properties ! Build.scala ! plugins.sbt lib/ logs/ target/ ! scala-2.10.0 test/

app/ ! assets ! stylesheets ! javascripts ! controllers ! helpers ! mailers ! models ! views config/ ! application.rb ! routes.rb ! database.ymlconfig.ru dbGemFilelib/ log/ public/script/test/ tmp/vendor/

Page 6: Play vs Rails

Console

Page 7: Play vs Rails

Dependenciesproject/Build.scala

val appDependencies = Seq( "postgresql" % "postgresql" % "8.4-702.jdbc4" "org.mockito" % "mockito-all" % "1.8.5" % "test")

Gemfile

gem "mysql2"group :test do gem "webmock"end

Maven

RubyGems

Page 8: Play vs Rails

Dependencies Support429.000 jars

mvnrepository.com

52,468 gemsrubygems.org

Page 9: Play vs Rails

Views TemplatesSTE (Scala Template Engine)

ERB (Embedded Ruby)

<title>    <%=  t("site.title")  %>  -­‐  <%=  yield(:title)  %></title><%=  video['title']  %>

@(title: String)(content: Html)

<title> @Messages("site.title") - @title</title>@{(video \ "title")(0).text}

Page 10: Play vs Rails

js / css

<%=  javascript_include_tag  :all,  :cache  =>  true  %>  <%=  stylesheet_link_tag  :all,  :cache  =>  true  %>

<link rel="stylesheet" href="@routes.Assets.at("stylesheets/grid.css")"><link rel="stylesheet" href="@routes.Assets.at("stylesheets/style.css")"><link rel="stylesheet" href="@routes.Assets.at("stylesheets/galleriffic.css")"><script src="@routes.Assets.at("javascripts/applicaton.js")" type="text/javascript" /><script src="@routes.Assets.at("javascripts/jquery.js")" type="text/javascript" />

Page 11: Play vs Rails

Links

<li  class="menu">    <%=  link_to  "#{t('site.singer')}",  {:controller  =>  "cantora"}  %></li>

<li class="menu"> <a href="@routes.Application.cantora">@Messages("site.singer")</a></li>

Page 12: Play vs Rails

Routes

map.connect  ':controller/:action/:id'

GET /cantora controllers.Application.cantoraGET /musicas controllers.Application.musicGET /agenda controllers.Application.showsGET /novidades controllers.Application.news

GET /clients/:id controllers.Clients.show(id: Long)

Page 13: Play vs Rails

Controllers

class  CantoraController  <  ApplicationControllerdef  index

   endendclass  NewsController  <  ApplicationController   def  index   endend

def cantora = Action { implicit request =>; Ok(views.html.cantora()) }def music = Action { implicit request =>; Ok(views.html.music()) }def shows = Action { implicit request => Ok(views.html.shows()) }def news = Action { implicit request => Ok(views.html.news()) }

/app/views/[controller_name]/index.erb.html

/app/views/[method_name].scala.html

Page 14: Play vs Rails

Databases

config/database.yml:

development:    adapter:  mysql2    database:  blog_development    username:  root    password:

conf/application.conf:

db.default.driver=com.mysql.jdbc.Driverdb.default.url="jdbc:mysql://localhost/playdb"db.default.user=playdbuserdb.default.pass="a strong password"

Page 15: Play vs Rails

Databases

Active  Record:

Country.all.map  do  |c|    if  (c.name  ==  “France”)        France.new    else  if  (c.pop  >  1000000)        BigCountry.new(c.name)    else        SmallCountry.new(c.name)    endend

SQL API:

val countries = SQL("Select name,population from Country")().collect { case Row("France", _) => France() case Row(name:String, pop:Int) if(pop > 1000000) => BigCountry(name) case Row(name:String, _) => SmallCountry(name) }

val result: Int = SQL("delete from City where id = {id}").on(“id” -> 99).executeUpdate()

Country.delete(99)

Page 16: Play vs Rails

Databases

Active  Record:

Country.all.map  do  |c|    if  (c.name  ==  “France”)        France.new    else  if  (c.pop  >  1000000)        BigCountry.new(c.name)    else        SmallCountry.new(c.name)    endend

Country.delete(99)

OGH(Old Good Hibernate)

Page 17: Play vs Rails

Migrations / Evolutions

class  CreateUsers  <  ActiveRecord::Migration    def  up        create_table  :users  do  |t|            t.string  :email            t.string  :password            t.timestamps        end    end    def  down        drop_table  :users    endend

# --- !Ups CREATE TABLE Users ( id bigint(20) NOT NULL AUTO_INCREMENT, email varchar(255) NOT NULL, password varchar(255) NOT NULL, PRIMARY KEY (id)); # --- !DownsDROP TABLE Users; conf/evolutions/{database name}/{#}.sql

db/migrate/{timestamp}_create_users.rb

run: AUTOMATIC!

run:  rake  db:migrate

Page 18: Play vs Rails

Web Services

class  VideosController  <  ApplicationController    def  index        uri  =  "http://gdata.youtube.com/feed.xml"        video_feed  =  RestClient.get(uri)        @videos  =  Hash.from_xml(video_feed)['feed']['entry']    endend

def videos = Action { implicit request => Async { val uri = "http://gdata.youtube.com/feed.xml" WS.url(uri).get().map { response => Ok(views.html.videos(response.xml \ "entry")) } }}

Page 19: Play vs Rails

XML

@videos  =  Hash.from_xml(video_feed)['feed']['entry']

<%  @videos.each  do  |video|  %>          <a  href="<%=  video['group']['player']['url']  %>">                  <%=  video['title']  %>          </a><%  end  %>

Ok(views.html.videos(response.xml \ "entry"))

@(videos: scala.xml.NodeSeq)

@videos.map { video =>    <a href="@{ ((video \\ "group") \\ "player")(0).attribute("url")}">       @{(video \ "title")(0).text}    </a>}

Page 20: Play vs Rails

JSON

WS.url("https://graph.facebook.com/daniella.alcarpe/albums").get().map  {  response  =>        val  albuns  =  (response.json  \  "data").            as[List[JsObject]].filter(album  =>                (album  \  "description").toString.equals("\"*\""))          val  photos  =  albuns.map  {  album  =>            WS.url("https://graph.facebook.com/"  +  (album  \  "id").toString.replace("\"",  "")  +  "/photos").get().map  {  response2  =>                (response2.json  \  "data").as[List[JsObject]].map  {  photo  =>                    ((photo  \  "images")(3)  \  "source").toString.replace("\"",  "")                }            }        }    Ok(views.html.photos(photos))}

@albuns_photos  =  {}        @albuns  =  []        albuns  =  JSON.parse(RestClient.get("https://graph.facebook.com/daniella.alcarpe/albums"))["data"]        albuns.each  do  |album|            if  (album['description']  ==  "*")                photos  =  JSON.parse(RestClient.get("https://graph.facebook.com/#{album['id']}/photos"))["data"]                albuns_photos  =  photos.map  {|p|  p["images"][3]["source"]}                album['photos']  =  albuns_photos                @albuns  <<  album            end        end

Page 21: Play vs Rails

Cache

class  VideosController  <  ApplicationController        caches_action  :index,  :expires_in  =>  1.dayend

def videos = Cached("videos", 18000) {  Action { ...  }}

Page 22: Play vs Rails

Unit Tests

test  "my  test"  do    array  =  [1,  2,  3]    assert_equal  1,  array.firstend

@Test def myTest() { val array = List(1, 2, 3) assert(array(0) === 1)}

Page 23: Play vs Rails

Specs

describe  "HelloWorldSpec"  docontext  "The  'Hello  world'  string  should"  do    it  "contain 11 characters"  do        "Hello  world".size.should  eq(11)    end    it  "end with 'world'"  do        "Hello  world".should  end_with("world")    endend

end

class HelloWorldSpec extends Specification { "The 'Hello world' string" should { "contain 11 characters" in { "Hello world" must have size(11) } "end with 'world'" in { "Hello world" must endWith("world") } }}

specs2

rspec

$ autospec

autotest:$ ~ test

Page 24: Play vs Rails

Deploy

$  heroku  create$  git  push  heroku  master

In Procfile:web: target/start -Dhttp.port=${PORT} -DapplyEvolutions.default=true -Ddb.default.url=${DATABASE_URL} -Ddb.default.driver=org.postgresql.Driver

In project/Build.scala:val appDependencies = Seq( "postgresql" % "postgresql" % "8.4-702.jdbc4")

$ heroku create$ git push heroku master

Page 25: Play vs Rails

Scala RubyX

by @danicuki

Adendo

Page 26: Play vs Rails

Lambda

list.select  do  |el|    el  <  100end  

list.filter(_ < 100)

list.filter { el: Int => (el < 100)}

Page 27: Play vs Rails

Types

Dynamic:

a  =  Hash.newa  =  “BOO!”

Static:

val a = new HashMap[Int, String]

Page 28: Play vs Rails

Pattern Matchingrequire  'case'def  matchTest  x  case  x  when  7      "seven"  when  "string"      0  when  Case::All[Integer]      "no."  when  Case::Array[2,Case::Any]      x[1..-­‐1]  endend

def myMatch(x: Any): Any = x match { case 7 => “seven” case “string” => 0 case y:Int => “no.” case 2 :: tail => tail}

Page 29: Play vs Rails

Monkey Patch

class  String    def  my_method      "yess!!!"    endend

puts  "a".my_method  #  =>  yess!!!

class MySuperString(original: String) { def myMethod = "yess!!!"}

implicit def string2super(x: String) = new MySuperString(x)

println("a".myMethod) // => yess!!!

Page 30: Play vs Rails

Dynamic Calls

class  Animal    def  method_missing  name,  *args        if  args.empty?            puts  "Animal  says  "  +  name.to_s        else            puts  "Animal  wants  to  "  +  name.to_s  +    args.join(",  ")        end        self    endend

class Animal extends Dynamic { def _select_(name: String) = println("Animal says " + name) def _invoke_(name: String, args: Any*) = { println("Animal wants to " + name + args.mkString(", ")) this }}

val animal = new Animalanimal.qualk // => Animal says qualkanimal.say("hello") // => Animal wants to say hello

animal  =  Animal.newanimal.qualk  #  =>  Animal  says  :  qualks  !animal.say("hello")  #  =>  Animal  wants  to  say  hello

Page 31: Play vs Rails

Modules / Traits

module  PimpMyClass    def  my_method        puts  "my_method"    endendclass  IncludeModule    include  PimpMyClassendIncludeModule.new.my_method

trait PimpMyClass { def myMethod = println("myMethod")}class IncludeTrait extends PimpMyClass(new IncludeTrait).myMethod

Page 32: Play vs Rails

Duck Typingclass Duck { def quack = ... def walk = ...}class Platypus { def quack = ... def walk = ...}

val duck = new Duckval platypus = new PlatypusActAsADuck(duck)ActAsADuck(platypus)

def ActAsADuck(a: { def quack; def walk })= { a.quack a.walk}

class  Duck    def  quack;  end    def  walk;  endend

class  Platypus    def  quack;  end    def  walk;  endend

duck  =  Duck.newplatypus  =  Platypus.newact_as_a_duck(duck)act_as_a_duck(platypus)

def  act_as_a_duck  animal    animal.quack    animal.walkend

Page 33: Play vs Rails

Actors

Page 34: Play vs Rails

Performance

0

20

40

60

80

2.07

39.74

70.74ScalaJRubyRuby

Source : http://shootout.alioth.debian.org

Page 36: Play vs Rails

Obrigado!@danicuki

www.agileandart.com