Más contenido relacionado La actualidad más candente (20) Similar a Ruby MVC from scratch with Rack (20) Ruby MVC from scratch with Rack1. Ruby MVC from scratch with Rack
I
Marco Schaden | @donschado | 23.08.2014RedFrog Conf
2. there was a rack application
handling 10.000+ req/sec
once upon a time
http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html
3. DISCLAIMER
no live coding: but we write and refactor a lot of code!
simple codez: examples try to be more obvious than "SOLID"!
• a newbie will learn some cool tricks!
• a pro will find a lot to complain ;)!
!seriously: this presentation contains all the memes, sorry
5. Rack is the foundation of all modern Ruby web frameworks
8. Write once, run "everywhere"
WEBrick!
Thin!
Puma!
Unicorn!
Passenger!
Torqbox /Torquebox!
Trinidad!
Mongrel!
Pow!
CGI!
SCGI!
FastCGI!
Ebb!
Fuzed!
Litespeed!
…
9. RackApp
+call(env)
A rack application is any Ruby object that responds to call. !
!
It takes the environment hash as argument!
and returns an array of exactly three values: !
the status, the headers and the body*!
!
*which must respond to each
13. !
->(env) { }[ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
14. !
->(env) { }
*run means "call that object for each request"
run [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
15. !
->(env) { }
*run means "call that object for each request"
# config.ru
run [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
16. !
->(env) { }
$ rackup
127.0.0.1 - - [23/Aug/2014 10:50:07] "GET / HTTP/1.1" 200 - 0.0007
[2014-08-23 10:50:00] INFO WEBrick 1.3.1
[2014-08-23 10:50:00] INFO ruby 2.1.1 (2014-02-24) [x86_64-darwin13.0]
[2014-08-23 10:50:00] INFO WEBrick::HTTPServer#start: pid=11802 port=9292
*run means "call that object for each request"
# config.ru
run [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
17. !
->(env) { }
$ rackup
127.0.0.1 - - [23/Aug/2014 10:50:07] "GET / HTTP/1.1" 200 - 0.0007
[2014-08-23 10:50:00] INFO WEBrick 1.3.1
[2014-08-23 10:50:00] INFO ruby 2.1.1 (2014-02-24) [x86_64-darwin13.0]
[2014-08-23 10:50:00] INFO WEBrick::HTTPServer#start: pid=11802 port=9292
*run means "call that object for each request"
SHIP IT
# config.ru
run [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
18. , read it: https://github.com/rack/rack
How does it work?
seriously
24. # config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
run -> e { Rack::Response.new(view) }
require 'erb'
view = <<-HTML
<!DOCTYPE html>
<html>
<head>
<title>Rack with
</head>
<body>
<div>
<h1>Hello World!</h1>
</div>
</body>
</html>
HTML
ERB</title>
<h1>Current time: <%= Time.now %></h1>
25. # config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
run -> e { Rack::Response.new(view) }
require 'erb'
view = <<-HTML
<!DOCTYPE html>
<html>
<head>
<title>Rack with
</head>
<body>
<div>
<h1>Hello World!</h1>
</div>
</body>
</html>
HTML
ERB</title>
<h1>Current time: <%= Time.now %></h1>
ERB.new(view).result) }
32. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
source "https://rubygems.org"
!
gem 'rack'
gem 'thin'
gem 'tilt'
33. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
<html>
<head>
<title>Frack MVC</title>
</head>
<body>
<h1>application#layout</h1>
<%= yield %>
</body>
</html>
35. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
# Your code goes here...
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
*use adds a middleware to the rack application stack created by Rack::Builder.
36. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
Rack::Response.new(env)
*use adds a middleware to the rack application stack created by Rack::Builder.
37. ["SERVER_SOFTWARE",."thin.1.6.2.codename.Doc.Brown"]
["SERVER_NAME",."localhost"]["rack.input",.
#<Rack::Lint::InputWrapper:0x007fc0421e1ea0.
@input=#<StringIO:0x007fc0421fb940>>]["rack.version",.[1,.
0]]["rack.errors",.#<Rack::Lint::ErrorWrapper:
0x007fc0421e1cc0.@error=#<IO:<STDERR>>>]
["rack.multithread",.false]["rack.multiprocess",.false]
["rack.run_once",.false]["REQUEST_METHOD",."GET"]
["REQUEST_PATH",."/"]["PATH_INFO",."/"]["REQUEST_URI",."/"]
["HTTP_VERSION",."HTTP/1.1"]["HTTP_USER_AGENT",."curl/
7.30.0"]["HTTP_HOST",."localhost:9292"]["HTTP_ACCEPT",."*/
*"]["GATEWAY_INTERFACE",."CGI/1.2"]["SERVER_PORT",."9292"]
["QUERY_STRING",.""]["SERVER_PROTOCOL",."HTTP/1.1"]
["rack.url_scheme",."http"]["SCRIPT_NAME",.""]
["REMOTE_ADDR",."127.0.0.1"]["async.callback",.#<Method:.
Thin::Connection#post_process>]["async.close",.
#<EventMachine::DefaultDeferrable:0x007fc0421fab08>]
38. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
env
39. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
40. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
render 'users/index'
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
41. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
def render(view)
render 'users/index'
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
42. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render 'users/index'
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
43. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
render 'users/index'
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
44. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
def render_template(path, &block)
render 'users/index'
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
45. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
render 'users/index'
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
48. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
render 'users/index'
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
!
!
!
!
!
&$ config.ru
49. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
render 'users/index'
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
!
!
!
!
!
&$ config.ru
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
50. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
html { font-family: sans-serif; }
h1 { color: #008040; }
h2 { color: #ff0080; }
51. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
<html>
<head>
<title>Frack MVC</title>
!
</head>
<body>
<h1>application#layout</h1>
<%= yield %>
</body>
</html>
52. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
<html>
<head>
<title>Frack MVC</title>
!
</head>
<body>
<h1>application#layout</h1>
<%= yield %>
</body>
</html>
<link rel="stylesheet" type="text/css" href="css/style.css">
53. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
end
end
end
!
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
render 'users/index'
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
54. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
end
end
end
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new( )
end
!
!
!
!
!
!
!
!
!
!
end
end
end
!
!
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
render 'users/index'
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
57. ["SERVER_SOFTWARE",."thin.1.6.2.codename.Doc.Brown"]
["SERVER_NAME",."localhost"]["rack.input",.
#<Rack::Lint::InputWrapper:0x007fc0421e1ea0.
@input=#<StringIO:0x007fc0421fb940>>]["rack.version",.[1,.
0]]["rack.errors",.#<Rack::Lint::ErrorWrapper:
0x007fc0421e1cc0.@error=#<IO:<STDERR>>>]
["rack.multithread",.false]["rack.multiprocess",.false]
["rack.run_once",.false]["REQUEST_METHOD",."GET"]
["REQUEST_PATH",""/"]["PATH_INFO",""/"]["REQUEST_URI",."/"]
["HTTP_VERSION",."HTTP/1.1"]["HTTP_USER_AGENT",."curl/
7.30.0"]["HTTP_HOST",."localhost:9292"]["HTTP_ACCEPT",."*/
*"]["GATEWAY_INTERFACE",."CGI/1.2"]["SERVER_PORT",."9292"]
["QUERY_STRING",.""]["SERVER_PROTOCOL",."HTTP/1.1"]
["rack.url_scheme",."http"]["SCRIPT_NAME",.""]
["REMOTE_ADDR",."127.0.0.1"]["async.callback",.#<Method:.
Thin::Connection#post_process>]["async.close",.
#<EventMachine::DefaultDeferrable:0x007fc0421fab08>]
remember env?
58. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
end
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
59. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
!
!
!
end
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
if env['PATH_INFO'] == '/'
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
60. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
Rack::Response.new(render 'users/index')
!
!
!
end
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(&block)
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
if env['PATH_INFO'] == '/'
else
Rack::Response.new('Not found', 404)
end
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
61. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
!
Rack::Response.new(render 'users/index')
!
!
!
end
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
if env['PATH_INFO'] == '/'
else
Rack::Response.new('Not found', 404)
end
&block)
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
62. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
!
Rack::Response.new(render 'users/index')
!
!
!
end
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
if env['PATH_INFO'] == '/'
else
Rack::Response.new('Not found', 404)
end
@users = ['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
&block)
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
63. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
!
Rack::Response.new(render 'users/index')
!
!
!
end
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
if env['PATH_INFO'] == '/'
else
Rack::Response.new('Not found', 404)
end
@users = ['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
&block) self,
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
65. <h2>users#index</h2>
!
!
!
!
!
<ul>
<% @users.each do |user| %>
<li><%= user %></li>
<% end %>
</ul>
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
69. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
render 'users/index')
@users = ['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
Rack::Response.new(
else
Rack::Response.new('Not found', 404)
end
end
70. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
Rack::Response.new(
else
Rack::Response.new('Not found', 404)
end
end
71. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
$LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
!
!
!
!
!
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
Rack::Response.new(
else
Rack::Response.new('Not found', 404)
end
end
UsersController.new.index)
72. $LOAD_PATH << '.'
require 'rack'
require 'tilt'
!
module Frack
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
!
!
!
!
!
!
!
!
!
!
!
!
end
end
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
73. Rack::Response.new('Not found', 404)
end
end
end
end
!
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
74. Rack::Response.new('Not found', 404)
end
end
end
end
!
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
&$ config.ru
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
77. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
!
!
!
!
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
78. require 'spec_helper'
!
Capybara.app = Rack::Builder.new do
eval(File.read(File.expand_path('./config.ru')))
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
!
!
!
!
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
79. require 'spec_helper'
!
Capybara.app = Rack::Builder.new do
eval(File.read(File.expand_path('./config.ru')))
end
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
!
!
!
!
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
describe 'users#index' do
before { visit '/' }
it 'renders layout' do
expect(page).to have_content('application#layout')
end
it 'renders index view' do
expect(page).to have_content('users#index')
end
it 'shows a list of users' do
expect(page).to have_selector('li',
text: /Stark|Parker|Wayne/, count: 3)
end
end
&$ config.ru
81. module Frack
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
!
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
!
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
82. frack-mvc
"
#$ Gemfile
#$ app
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
module Frack
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
!
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
end
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
!
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
REFACTOR
ALL THE FRACK
83. !
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
frack-mvc
"
#$ Gemfile
#$ app
84. " #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
!
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
frack-mvc
"
#$ Gemfile
#$ app
85. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
module Frack
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
end
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
86. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
require 'app/controllers/users_controller'
module Frack
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
end
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
87. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
require 'app/models/user'
require 'app/controllers/users_controller'
module Frack
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
end
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
88. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
require 'app/models/user'
require 'app/controllers/users_controller'
require 'lib/frack'
module Frack
!!
!
!
!
!
!
!
!
!!
!
!
!
!
!
!
!
!
!!
!
end
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
89. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
require 'app/models/user'
require 'app/controllers/users_controller'
require 'lib/frack'
module Frack
!!
!
!
!
!
!
!
!
!!
!
!
!
!
!
!
!
!
!!
!
end
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
90. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
!
class UsersController < Frack::BaseController
def index
@users = User.all
render 'users/index'
end
end
class User
def self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
end
end
require 'app/models/user'
require 'app/controllers/users_controller'
require 'lib/frack'
module Frack
!!
!
!
!
!
!
!
!
!!
!
!
!
!
!
!
!
!
!!
!
end
class Application
class << self
def call(env)
if env['PATH_INFO'] == '/'
Rack::Response.new(UsersController.new.index)
else
Rack::Response.new('Not found', 404)
end
end
end
end
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new("app/views/#{path}.html.erb").render(self, &block)
end
end
91. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << '.'
!
require 'lib/frack'
require 'app/controllers/users_controller'
require 'app/models/user'
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
92. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
!
require 'rack'
require 'tilt'
!
module Frack
autoload :Application, 'frack/application'
autoload :BaseController, 'frack/base_controller'
end
93. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
"app/views/#{ }.html. ).render(self, &block)
end
end
erb"path
94. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
"app/views/#{ }.html. ).render(self, &block)
end
end
*"path
95. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
).render(self, &block)
end
end
path
96. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
).render(self, &block)
end
end
file( )path
97. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
).render(self, &block)
end
end
def file(path)
Dir[ ]
end
file( )path
98. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
).render(self, &block)
end
end
def file(path)
Dir[ ]
end
File.join('app', 'views', "#{path}.html.*")
file( )path
99. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
).render(self, &block)
end
end
def file(path)
Dir[ ]
end
File.join('app', 'views', "#{path}.html.*") .first
file( )path
100. module Frack
class BaseController
def render(view)
render_template('layouts/application') do
render_template(view)
end
end
!
def render_template(path, &block)
Tilt.new(
end
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
).render(self, &block)
end
end
def file(path)
Dir[ ]
end
File.join('app', 'views', "#{path}.html.*") .first
file( )path
AWESOME!
support all the template engines
105. Middleware Stack
use Rack::Static
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
HTTPrequest
*a middleware is a rack application that wraps up an inner application.
106. Middleware Stack
use Rack::Static
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
HTTPrequest
HTTPresponse
*a middleware is a rack application that wraps up an inner application.
107. Middleware Stack
use Rack::Static
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
HTTPrequest
HTTPresponse
module Rack
class ContentLength
def initialize(app)
@app = app
end
!
def call(env)
status, headers, body = @app.call(env)
# [...]
# headers['Content-Length'] = length.to_s
# [...]
[status, headers, body]
end
end
end
*a middleware is a rack application that wraps up an inner application.
108. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << '.'
!
require 'lib/frack'
require 'app/controllers/users_controller'
require 'app/models/user'
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
!
run Frack::Application
109. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << '.'
!
require 'lib/frack'
require 'app/controllers/users_controller'
require 'app/models/user'
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
!
run Frack::Application
use Frack::Router
110. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
!
require 'rack'
require 'tilt'
!
module Frack
!
autoload :Application, 'frack/application'
autoload :BaseController, 'frack/base_controller'
end
111. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << File.expand_path(File.dirname(__FILE__))
!
require 'rack'
require 'tilt'
!
module Frack
!
autoload :Application, 'frack/application'
autoload :BaseController, 'frack/base_controller'
end
autoload :Router, 'frack/router'
112. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
module Frack
class Router
attr_reader :app
!
def initialize(app)
@app = app
end
!
def call(env)
app.call(env)
end
end
end
113. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
app.call(env)
114. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
ROUTES = {
'/' =>
}
app.call(env)
115. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
ROUTES = {
'/' =>
}
app.call(env)
{ 'controller' => 'users', 'action' => 'index' },
116. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
ROUTES = {
'/' =>
}
app.call(env)
{ 'controller' => 'users', 'action' => 'index' },
117. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(mapping)
ROUTES = {
'/' =>
}
app.call(env)
{ 'controller' => 'users', 'action' => 'index' },
118. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(mapping)
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
{ 'controller' => 'users', 'action' => 'index' },
119. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(mapping)
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
120. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
mapping)
121. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
def controller_action(mapping)
mapping)
122. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
def controller_action(mapping)
controller_action( )mapping)
123. module Frack
class Router
attr_reader :app
!
!
!
!
!
def initialize(app)
@app = app
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
end
end
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = ROUTES[env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
124. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if env['PATH_INFO'] == '/'
else
Rack::Response.new('Not found', 404)
end
UsersController.new.index)Rack::Response.new(
end
end
end
def call(env)
end
125. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
UsersController.new.index)Rack::Response.new(
end
end
end
def call(env)
end
126. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
Rack::Response.new(
end
end
end
def call(env)
end
127. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
*dispatch)Rack::Response.new(
end
end
end
def call(env)
end
128. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
*dispatch)Rack::Response.new(
end
end
end
def call(env)
attr_accessor :env
self.env = env
end
129. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
*dispatch)Rack::Response.new(
end
end
end
def call(env)
attr_accessor :env
self.env = env
end
def dispatch
controller.new.public_send(env['action'])
end
130. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
*dispatch)Rack::Response.new(
end
end
end
def call(env)
attr_accessor :env
self.env = env
end
def dispatch
controller.new.public_send(env['action'])
end
def controller
131. module Frack
class Application
class << self
!
!
!
!
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
*dispatch)Rack::Response.new(
end
end
end
def call(env)
attr_accessor :env
self.env = env
end
def dispatch
controller.new.public_send(env['action'])
end
def controller
Object.const_get(env['controller'].capitalize + 'Controller')
end
133. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << '.'
!
require 'lib/frack'
require 'app/controllers/users_controller'
require 'app/models/user'
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
!
!
!
!
use Frack::Router
run Frack::Application
134. frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
$LOAD_PATH << '.'
!
require 'lib/frack'
require 'app/controllers/users_controller'
require 'app/models/user'
!
use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']
use Rack::CommonLogger
use Rack::ContentLength
!
!
!
!
use Frack::Router do
match '/' => 'users#index'
end
run Frack::Application
135. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
def initialize(app)
@app = app
end
end
ROUTES
136. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
ROUTES = {
'/' =>
}
app.call(env)
'users#index'
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
def initialize(app)
@app = app
end
end
ROUTES
137. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
app.call(env)
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
routes
def initialize(app)
@app = app
end
end
138. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
app.call(env)
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
routes
def initialize(app)
@app = app
end
end
, &block)
139. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
app.call(env)
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
@routes = {}
routes
def initialize(app)
@app = app
end
end
, &block)
140. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
app.call(env)
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
@routes = {}
instance_eval(&block) if block_given?
routes
def initialize(app)
@app = app
end
end
, &block)
141. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
app.call(env)
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
@routes = {}
instance_eval(&block) if block_given?
routes
def match(route)
def initialize(app)
@app = app
end
end
, &block)
142. module Frack
class Router
attr_reader :app
!
!
!
!
!
!
!
end
!
def call(env)
!
!
!
!
!
end
!
!
!
!
!
!
!
!
!
frack-mvc
"
#$ Gemfile
#$ app
" #$ controllers
" " &$ users_controller.rb
" #$ models
" " &$ user.rb
" &$ views
" #$ layouts
" " &$ application.html.erb
" &$ users
" &$ index.html.erb
#$ lib
" #$ frack
" " #$ application.rb
" " #$ base_controller.rb
" " &$ router.rb
" &$ frack.rb
#$ public
" #$ css
" " &$ style.css
" #$ images
" &$ js
#$ spec
" #$ integration
" " &$ user_spec.rb
" &$ spec_helper.rb
&$ config.ru
if (mapping = [env['PATH_INFO']])
env.merge!(
else
Rack::Response.new('Not found', 404)
end
app.call(env)
def controller_action(mapping)
Hash[ %w(controller action).zip mapping.split('#') ]
end
controller_action( )mapping)
, :routes
@routes = {}
instance_eval(&block) if block_given?
routes
def match(route)
self.routes.merge!(route)
end
def initialize(app)
@app = app
end
end
, &block)
146. Challenges for the curious ones:
!
• params!
• redirect_to!
• partial rendering!
• implicit call to render!
• routing with placeholders!
• routing with specific http verbs!
• error handling!
• session management!
• flash messages!
• persistence!
• security stuff and protection!
• different mime types!
• url helper!
• better class loading / autoloading!
• asset management
Rebuilding Rails features, is a great opportunity to learn how they work.
147. yes, you should definitely do this at home
but maybe not in production
love the Rails core team for their amazing work
150. Marco Schaden | @donschado | 23.08.2014RedFrog Conf
Marco @DonSchado - 17 Std.
rackup -r rack/lobster -b 'run Rack::Lobster.new'