Ruby MVC from scratch with Rack
-
Upload
donschado -
Category
Technology
-
view
796 -
download
1
description
Transcript of Ruby MVC from scratch with Rack
![Page 1: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/1.jpg)
Ruby MVC from scratch with Rack
I
Marco Schaden | @donschado | 23.08.2014RedFrog Conf
![Page 2: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/2.jpg)
there was a rack applicationhandling 10.000+ req/sec
once upon a time
http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html
![Page 3: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/3.jpg)
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
![Page 4: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/4.jpg)
![Page 5: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/5.jpg)
Rack is the foundation of all modern Ruby web frameworks
![Page 6: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/6.jpg)
http://chneukirchen.org/talks/euruko-2007/neukirchen07introducingrack.pdf
![Page 7: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/7.jpg)
http://chneukirchen.org/talks/euruko-2007/neukirchen07introducingrack.pdf
• specification!• implementation!• minimal abstract API for HTTP!• Request: CGI environment!• Response: status, headers, body
common interface between
server and application
![Page 8: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/8.jpg)
Write once, run "everywhere"
WEBrick!Thin!Puma!
Unicorn!Passenger!
Torqbox / Torquebox!Trinidad!Mongrel!
Pow!CGI!SCGI!
FastCGI!Ebb!
Fuzed!Litespeed!
…
![Page 9: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/9.jpg)
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
![Page 10: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/10.jpg)
<<"show"me"the"code">>
![Page 11: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/11.jpg)
! ->(env) { }
![Page 12: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/12.jpg)
! ->(env) { }[ ]
![Page 13: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/13.jpg)
! ->(env) { }[ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
![Page 14: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/14.jpg)
! ->(env) { }
*run means "call that object for each request"
run [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
![Page 15: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/15.jpg)
! ->(env) { }
*run means "call that object for each request"
# config.rurun [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
![Page 16: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/16.jpg)
! ->(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.rurun [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
![Page 17: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/17.jpg)
! ->(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.rurun [ ]200, {'Content-Type' => 'text/html'}, ['Hello World!']
![Page 19: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/19.jpg)
HTML + ERB
![Page 20: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/20.jpg)
# config.rurun -> e { [200, {'Content-Type' => 'text/html'}, ['Hello World!']] }
![Page 21: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/21.jpg)
# config.rurun -> e { Rack::Response.new('Hello World!') }
![Page 22: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/22.jpg)
# config.rurun -> e { Rack::Response.new(view) }
![Page 23: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/23.jpg)
# config.ru!!!!!!!!!!!!!!!!run -> e { Rack::Response.new(view) }
view = <<-HTML <!DOCTYPE html> <html> <head> <title>Rack with HTML</title> </head> <body> <div> <h1>Hello World!</h1> </div> </body> </html>HTML
![Page 24: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/24.jpg)
# 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>
![Page 25: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/25.jpg)
# 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) }
![Page 26: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/26.jpg)
Current time: 2014-08-23 10:54:29 +0200
![Page 27: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/27.jpg)
</introduction>
![Page 28: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/28.jpg)
MVC
![Page 29: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/29.jpg)
froscon-rack-mvc
![Page 30: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/30.jpg)
frack-mvc
![Page 31: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/31.jpg)
frack-mvc"#$ Gemfile#$ app" &$ views" #$ layouts" " &$ application.html.erb" &$ users" &$ index.html.erb&$ config.ru
![Page 32: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/32.jpg)
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'
![Page 33: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/33.jpg)
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>
![Page 34: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/34.jpg)
frack-mvc"#$ Gemfile#$ app" &$ views" #$ layouts" " &$ application.html.erb" &$ users" &$ index.html.erb&$ config.ru
<h2>users#index</h2>
![Page 35: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/35.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
*use adds a middleware to the rack application stack created by Rack::Builder.
![Page 36: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/36.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
Rack::Response.new(env)
*use adds a middleware to the rack application stack created by Rack::Builder.
![Page 37: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/37.jpg)
["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>]
![Page 38: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/38.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
env
![Page 39: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/39.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new( ) end!!!!!!!!!! !!!!!
end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 40: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/40.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 41: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/41.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 42: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/42.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 43: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/43.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 44: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/44.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 45: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/45.jpg)
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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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 endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 46: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/46.jpg)
application#layout!!users#index
![Page 47: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/47.jpg)
application#layout!!users#index
but can I haz style?
![Page 48: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/48.jpg)
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new(render 'users/index') end end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new( ) end!!!!!!!!!! end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 49: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/49.jpg)
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new(render 'users/index') end end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new( ) end!!!!!!!!!! end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 50: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/50.jpg)
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; }
![Page 51: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/51.jpg)
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>
![Page 52: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/52.jpg)
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">
![Page 53: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/53.jpg)
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new(render 'users/index') end end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new( ) end!!!!!!!!!! end endend!!use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 54: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/54.jpg)
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new(render 'users/index') end end endend!use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
$LOAD_PATH << '.'require 'rack'require 'tilt'!module Frack class Application class << self def call(env) Rack::Response.new( ) end!!!!!!!!!! end endend!!use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 55: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/55.jpg)
application#layout !users#index
![Page 56: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/56.jpg)
application#layout !users#index
what about simple routing?
and list some users?
![Page 57: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/57.jpg)
["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?
![Page 58: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/58.jpg)
$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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
frack-mvc"#$ Gemfile#$ app" &$ views" #$ layouts" " &$ application.html.erb" &$ users" &$ index.html.erb#$ public" #$ css" " &$ style.css" #$ images" &$ js&$ config.ru
![Page 59: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/59.jpg)
$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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 60: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/60.jpg)
$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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
if env['PATH_INFO'] == '/'
elseRack::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
![Page 61: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/61.jpg)
$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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 62: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/62.jpg)
$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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 63: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/63.jpg)
$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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun 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
![Page 64: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/64.jpg)
<h2>users#index</h2>!!!!!
frack-mvc"#$ Gemfile#$ app" &$ views" #$ layouts" " &$ application.html.erb" &$ users" &$ index.html.erb#$ public" #$ css" " &$ style.css" #$ images" &$ js&$ config.ru
![Page 65: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/65.jpg)
<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
![Page 66: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/66.jpg)
![Page 67: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/67.jpg)
![Page 68: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/68.jpg)
not sure if MVC…
![Page 69: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/69.jpg)
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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
render 'users/index')@users = ['Anthony Stark', 'Peter Parker', 'Bruce Wayne']
Rack::Response.new( else Rack::Response.new('Not found', 404) end end
![Page 70: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/70.jpg)
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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
Rack::Response.new( else Rack::Response.new('Not found', 404) end end
![Page 71: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/71.jpg)
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 endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
Rack::Response.new( else Rack::Response.new('Not found', 404) end end
UsersController.new.index)
![Page 72: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/72.jpg)
$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!!!!!!!!!!!! endend!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun Frack::Application
frack-mvc"#$ Gemfile#$ app" &$ views" #$ layouts" " &$ application.html.erb" &$ users" &$ index.html.erb#$ public" #$ css" " &$ style.css" #$ images" &$ js&$ config.ru
endend
class BaseControllerdef render(view) render_template('layouts/application') do render_template(view) endend!def render_template(path, &block) Tilt.new("app/views/#{path}.html.erb").render(self, &block)end
![Page 73: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/73.jpg)
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 endend!!!!!!!!!!!!!!!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun 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::BaseControllerdef index
@users = User.allrender 'users/index'
endend
![Page 74: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/74.jpg)
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 endend!!!!!!!!!!!!!!!use Rack::Static, root: 'public', urls: ['/images', '/js', '/css']use Rack::CommonLoggeruse Rack::ContentLengthrun 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::BaseControllerdef index
@users = User.allrender 'users/index'
endend
class Userdef self.all
['Anthony Stark', 'Peter Parker', 'Bruce Wayne']end
end
![Page 75: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/75.jpg)
![Page 76: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/76.jpg)
PROVE IT!
![Page 77: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/77.jpg)
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
![Page 78: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/78.jpg)
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
![Page 79: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/79.jpg)
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' dobefore { visit '/' }
it 'renders layout' doexpect(page).to have_content('application#layout')
end
it 'renders index view' doexpect(page).to have_content('users#index')
end
it 'shows a list of users' doexpect(page).to have_selector('li',text: /Stark|Parker|Wayne/, count: 3)
endend
&$ config.ru
![Page 80: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/80.jpg)
$ rspec!users#index renders layout renders index view shows a list of users!Finished in 0.02326 seconds 3 examples, 0 failures!Randomized with seed 13626
![Page 81: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/81.jpg)
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 endend!class UsersController < Frack::BaseController def index @users = User.all render 'users/index' endend!class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 82: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/82.jpg)
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 endend!class UsersController < Frack::BaseController def index @users = User.all render 'users/index' endend!class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
REFACTOR ALL THE FRACK
![Page 83: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/83.jpg)
!" &$ 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
![Page 84: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/84.jpg)
" #$ 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
![Page 85: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/85.jpg)
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' endend
class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 86: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/86.jpg)
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' endend
class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 87: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/87.jpg)
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' endend
class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 88: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/88.jpg)
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' endend
class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 89: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/89.jpg)
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' endend
class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 90: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/90.jpg)
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' endend
class User def self.all ['Anthony Stark', 'Peter Parker', 'Bruce Wayne'] endend
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
![Page 91: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/91.jpg)
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::CommonLoggeruse Rack::ContentLengthrun Frack::Application
![Page 92: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/92.jpg)
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
![Page 93: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/93.jpg)
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)
endend
erb"path
![Page 94: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/94.jpg)
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)
endend
*"path
![Page 95: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/95.jpg)
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)
endend
path
![Page 96: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/96.jpg)
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)
endend
file( )path
![Page 97: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/97.jpg)
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)
endend
def file(path)Dir[ ]
end
file( )path
![Page 98: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/98.jpg)
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)
endend
def file(path)Dir[ ]
endFile.join('app', 'views', "#{path}.html.*")
file( )path
![Page 99: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/99.jpg)
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)
endend
def file(path)Dir[ ]
endFile.join('app', 'views', "#{path}.html.*") .first
file( )path
![Page 100: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/100.jpg)
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)
endend
def file(path)Dir[ ]
endFile.join('app', 'views', "#{path}.html.*") .first
file( )path
AWESOME!support all the template engines
![Page 101: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/101.jpg)
better routing?magic?
MVC
![Page 102: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/102.jpg)
What if the router could be middleware?
![Page 103: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/103.jpg)
Middleware Stack
*a middleware is a rack application that wraps up an inner application.
![Page 104: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/104.jpg)
Middleware Stack
HT
TP
requ
est
*a middleware is a rack application that wraps up an inner application.
![Page 105: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/105.jpg)
Middleware Stack
use Rack::Static
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
HT
TP
requ
est
*a middleware is a rack application that wraps up an inner application.
![Page 106: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/106.jpg)
Middleware Stack
use Rack::Static
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
HT
TP
requ
est
HT
TP
resp
onse
*a middleware is a rack application that wraps up an inner application.
![Page 107: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/107.jpg)
Middleware Stack
use Rack::Static
use Rack::CommonLogger
use Rack::ContentLength
run Frack::Application
HT
TP
requ
est
HT
TP
resp
onse
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 endend
*a middleware is a rack application that wraps up an inner application.
![Page 108: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/108.jpg)
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::CommonLoggeruse Rack::ContentLength!run Frack::Application
![Page 109: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/109.jpg)
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::CommonLoggeruse Rack::ContentLength!run Frack::Applicationuse Frack::Router
![Page 110: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/110.jpg)
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
![Page 111: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/111.jpg)
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'
![Page 112: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/112.jpg)
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 endend
![Page 113: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/113.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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)
![Page 114: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/114.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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)
![Page 115: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/115.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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' },
![Page 116: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/116.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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' },
![Page 117: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/117.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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' },
![Page 118: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/118.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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)
elseRack::Response.new('Not found', 404)
end
ROUTES = {'/' =>
}
app.call(env)
{ 'controller' => 'users', 'action' => 'index' },
![Page 119: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/119.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end endend
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)
elseRack::Response.new('Not found', 404)
end
ROUTES = {'/' =>
}
app.call(env)
'users#index'
![Page 120: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/120.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end!!!! endend
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)
![Page 121: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/121.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end!!!! endend
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)
![Page 122: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/122.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end!!!! endend
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)
![Page 123: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/123.jpg)
module Frack class Router attr_reader :app!!!!! def initialize(app) @app = app end! def call(env) !!!!! end!!!! endend
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)
![Page 124: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/124.jpg)
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'] == '/'
elseRack::Response.new('Not found', 404)
end
UsersController.new.index)Rack::Response.new(
end endend
def call(env)
end
![Page 125: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/125.jpg)
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 endend
def call(env)
end
![Page 126: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/126.jpg)
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 endend
def call(env)
end
![Page 127: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/127.jpg)
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 endend
def call(env)
end
![Page 128: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/128.jpg)
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 endend
def call(env)
attr_accessor :env
self.env = env
end
![Page 129: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/129.jpg)
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 endend
def call(env)
attr_accessor :env
self.env = env
end
def dispatchcontroller.new.public_send(env['action'])
end
![Page 130: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/130.jpg)
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 endend
def call(env)
attr_accessor :env
self.env = env
end
def dispatchcontroller.new.public_send(env['action'])
end
def controller
![Page 131: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/131.jpg)
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 endend
def call(env)
attr_accessor :env
self.env = env
end
def dispatchcontroller.new.public_send(env['action'])
end
def controllerObject.const_get(env['controller'].capitalize + 'Controller')
end
![Page 132: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/132.jpg)
What if the router could take a block?
![Page 133: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/133.jpg)
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::CommonLoggeruse Rack::ContentLength!!!!
use Frack::Routerrun Frack::Application
![Page 134: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/134.jpg)
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::CommonLoggeruse Rack::ContentLength!!!!
use Frack::Router domatch '/' => 'users#index'
end
run Frack::Application
![Page 135: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/135.jpg)
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
endend
ROUTES
![Page 136: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/136.jpg)
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
endend
ROUTES
![Page 137: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/137.jpg)
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
endend
![Page 138: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/138.jpg)
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
endend
, &block)
![Page 139: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/139.jpg)
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
endend
, &block)
![Page 140: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/140.jpg)
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
endend
, &block)
![Page 141: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/141.jpg)
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
endend
, &block)
![Page 142: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/142.jpg)
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
endend
, &block)
![Page 143: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/143.jpg)
in ~ 50-100 LOCMVC
![Page 144: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/144.jpg)
![Page 145: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/145.jpg)
I haven't shown you all of it
![Page 146: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/146.jpg)
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.
![Page 147: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/147.jpg)
yes, you should definitely do this at home
but maybe not in production
love the Rails core team for their amazing work
![Page 149: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/149.jpg)
Marco Schaden | @donschado | 23.08.2014RedFrog Conf
kthxbye
![Page 150: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/150.jpg)
Marco Schaden | @donschado | 23.08.2014RedFrog Conf
Marco @DonSchado - 17 Std.rackup -r rack/lobster -b 'run Rack::Lobster.new'
![Page 151: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/151.jpg)
Backup
![Page 152: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/152.jpg)
Appendix: Rack in the wild
![Page 153: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/153.jpg)
http
://gu
ides
.ruby
onra
ils.o
rg/ra
ils_o
n_ra
ck.ht
ml
![Page 154: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/154.jpg)
\m/ActionController ::Metal
![Page 155: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/155.jpg)
http://api.rubyonrails.org/classes/ActionController/Metal.html
class HelloController < ActionController::Metal def index self.response_body = "Hello World!" endend
get 'hello', to: HelloController.action(:index)
*returns a valid Rack application for the Rails router to dispatch to
![Page 156: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/156.jpg)
http://api.rubyonrails.org/classes/ActionController/Metal.html
class HelloController < ActionController::Metal def index self.response_body = "Hello World!" endend
get 'hello', to: HelloController.action(:index)
OMG WHY?
*returns a valid Rack application for the Rails router to dispatch to
![Page 157: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/157.jpg)
http://api.rubyonrails.org/classes/ActionController/Metal.html
class HelloController < ActionController::Metal def index self.response_body = "Hello World!" endend
get 'hello', to: HelloController.action(:index)
• maybe to extract lightweight micro services
OMG WHY?
*returns a valid Rack application for the Rails router to dispatch to
![Page 158: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/158.jpg)
http://api.rubyonrails.org/classes/ActionController/Metal.html
class HelloController < ActionController::Metal def index self.response_body = "Hello World!" endend
get 'hello', to: HelloController.action(:index)
• maybe to extract lightweight micro services • to improve the performance of any API endpoint
OMG WHY?
*returns a valid Rack application for the Rails router to dispatch to
![Page 159: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/159.jpg)
http://api.rubyonrails.org/classes/ActionController/Metal.html
class HelloController < ActionController::Metal def index self.response_body = "Hello World!" endend
get 'hello', to: HelloController.action(:index)
• maybe to extract lightweight micro services • to improve the performance of any API endpoint• because all benefits of rails are "just a few" includes away
OMG WHY?
*returns a valid Rack application for the Rails router to dispatch to
![Page 160: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/160.jpg)
http://api.rubyonrails.org/classes/ActionController/Metal.html
class HelloController < ActionController::Metal def index self.response_body = "Hello World!" endend
get 'hello', to: HelloController.action(:index)
• maybe to extract lightweight micro services • to improve the performance of any API endpoint• because all benefits of rails are "just a few" includes away
OMG WHY?
*returns a valid Rack application for the Rails router to dispatch to
class HelloController < ActionController::Metal include AbstractController::Rendering include ActionView::Layouts append_view_path "#{Rails.root}/app/views"! def index render "hello/index" end! # Ensure ActiveSupport::Notifications events are fired include ActionController::Instrumentationend
![Page 161: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/161.jpg)
Backup Backup
![Page 162: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/162.jpg)
http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html
"every possible rack server on every possible Ruby, every possible web framework"
![Page 163: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/163.jpg)
Spoiler Alert!
![Page 164: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/164.jpg)
"The fastest framework is Rack. !Plain old Rack with no framework at all."
Spoiler Alert!
![Page 165: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/165.jpg)
"The fastest framework is Rack. !Plain old Rack with no framework at all."
Ruby 2.1 + Thin + Rack can hit 6301 req/sec
Spoiler Alert!
![Page 166: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/166.jpg)
"The fastest framework is Rack. !Plain old Rack with no framework at all."
Ruby 2.1 + Thin + Rack can hit 6301 req/sec=> Sinatra only manages !! ! 2505 req/sec.
Spoiler Alert!
![Page 167: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/167.jpg)
"The fastest framework is Rack. !Plain old Rack with no framework at all."
Ruby 2.1 + Thin + Rack can hit 6301 req/sec=> Sinatra only manages !! ! 2505 req/sec.=> Rails only does ! ! ! ! 1455 req/sec
Spoiler Alert!
![Page 168: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/168.jpg)
"The fastest framework is Rack. !Plain old Rack with no framework at all."
Ruby 2.1 + Thin + Rack can hit 6301 req/sec=> Sinatra only manages !! ! 2505 req/sec.=> Rails only does ! ! ! ! 1455 req/sec
"So, by simply using those frameworks on top of Rack, you give up over 60% of your maximum possible throughput."
Spoiler Alert!
![Page 169: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/169.jpg)
Spoiler spoiler Alert!
"Standard Ruby + Thin/Unicorn + Rails !is about the slowest possible combination"
![Page 170: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/170.jpg)
Spoiler spoiler Alert!
"Standard Ruby + Thin/Unicorn + Rails !is about the slowest possible combination"
the fastest:
![Page 171: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/171.jpg)
Spoiler spoiler Alert!
+
"Standard Ruby + Thin/Unicorn + Rails !is about the slowest possible combination"
the fastest:
![Page 172: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/172.jpg)
Spoiler spoiler Alert!
On a plain old Rack app it did 10.159 req/sec.
+
"Standard Ruby + Thin/Unicorn + Rails !is about the slowest possible combination"
the fastest:
![Page 173: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/173.jpg)
*I think these benchmarks are a little bit unfair, !when you compare a full rails stack vs. a rack one-liner.!
But I think the main message is valid:!Do you need the full stack for every request?
Logging
Sessions
Cookies
Security
Caching
Error Handling
Routing
![Page 174: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/174.jpg)
# hello_world.rbrequire 'rack'!!!!!!!!
app = Rack::Builder.new do !!!end
$ ruby hello_world.rb
# config.rurun ->(env) { [200, {'Content-Type' => 'text/html'}, ['Hello World!']] }
$ rackup
map '/' do! end
Rack::Handler::WEBrick.run app, :Port => 9292
run ->(env) { [200, {'Content-Type' => 'text/html'}, ['Hello World!']] }
use Rack::CommonLogger
$ ruby -r rack -e 'Rack::Handler::Thin.run lambda { |env| [200, {}, ["ok"]] }'
$ rackup -b 'run proc { [200, {}, [Time.now.to_s]] }'
for the curious:
![Page 175: Ruby MVC from scratch with Rack](https://reader038.fdocuments.us/reader038/viewer/2022102809/555a448ed8b42ae1398b5085/html5/thumbnails/175.jpg)
that’s all