SlideShare a Scribd company logo
1 of 74
Download to read offline
From zero to (almost)
Ruby on Rails in about a
million slides.
e.g. How the tubes go with a dash of
Ruby and almost Rails
- Me… Paraphrasing Euclid to King Ptolemy I Soter
“There is no royal road to Rails (or
Geometry)”
Ruby on Rails always seems
to be taught in one fo two
ways:
1. Install Ruby. Install Rails. Type
rails new <project name>. 

Type rails server and then visit http://
localhost:3000. Done. 



or…
2. An introduction to “ActiveRecord”!
NOPE!
The first way doesn’t teach
you how to build anything
in Rails!
… The second way presumes a great deal
of knowledge a new developer may not
have about the web, databases, etc.
The Web
Circa 1999
In 1999 the web was a very simple place.
A web browser loaded a "web page", a static
piece of content from a "web server", whose
only real job was to send files over the
magic internets.
A web page was not a single piece of
content but rather a single HTML file that
may also have some images and links in it.
It also probably had some ordered or
unordered lists of information, a few
paragraphs, and some blinking text.
The web today
e.g. Space LASERs
Fundamentally nothing has changed.
We still have web-servers that pass
files around but…
lots and lots of layers of
"magic" (e.g. technology) stand
between those files and a user
interacting with a website.
Modern "websites" are "web
applications" for the most part.
The distinction between a "site" and
an "application" centers around
dynamic content (e.g. content that
responds to your input as a user)
Applications often maintain "state" that
can be “persisted” e.g. there are users
or accounts or pictures of cats that
remember your name between visits.
The High-Level picture!
e.g. gnomes and unicorns
?
??
Browser
?
We are not going to explain the
"gnomes" in much detail here.
People with titles like "network
engineer" and "infrastructure
engineer” make that happen. (If we
want to dig into that we can do that
another time)
Our real goal here is to have an
intuition for how unicorns (e.g. Web
Applications) work in that picture.
GNOMES!
e.g. HTTP(S)
Gnomes are magical creatures. The
internet feeds on their labor.
One type of very nice Gnome is a
"TCP/IP" gnome. All you need to
know about them is that they work
very very closely with another guild of
Gnomes called “HTTP(S)" Gnomes.
TCP/IP is an internet "protocol" (e.g.
set of rules) for moving data around
in very systematic ways.
One type of data is HTTP(S) data.
HTTP and HTTP(S) are mostly the same.
The latter is encrypted where the prior
is not. (Hint: “S” is for “Secure”)
That's the only real difference so we
will just talk about HTTP here.
Everything we say about HTTP will
_also_ be true of HTTP(S) only
(magically) encrypted.
A reasonable metaphor for the rest of this talk on
Gnomes is that HTTP(S) gnomes hand data to the
TCP/IP Gnomes (Actually, TCP and IP gnomes are
two different sets of Gnomes wearing slightly
different color tunics) who make sure HTTP stuff
goes somewhere and gets back in the way we
expect.
HTTP(S)
Gnomes!
HTTP(S) Gnomes
HTTP is the protocol on which the web works.
It stands for HyperText Transfer Protocol and is the
backbone of the web.
HTTP is actually a very simple protocol at first glance:
HTTP defines verbs.
"Web Servers" are programs that know how to interpret
those verbs and the subjects they act on.
The most important (e.g. fundamental) verb in HTTP is GET
with which you ask a web-server to give you something e.g.
a webpage or an image (or pizza).
The High-Level picture!
e.g. named gnomes and unicorns
GET
?HTTP(S)
Browser
TCP/IP
GET a Pizza!
GET /pizza?topping=extra%20cheese
Hint: %20 is a space on the internet
require 'sinatra'
get '/pizza' do
if params[:topping]
"Sending you a pizza with #{params[:topping]}"
else
"Sending you a cheese pizza!"
end
end
In fact, you can write a _tiny_ Ruby
program using “Sinatra” that makes this
actually work:
$ ruby pizza.rb
== Sinatra/1.4.5 has taken the stage on 4567 for
development with backup from Thin
Thin web server (v1.6.3 codename Protein Powder)
Maximum connections set to 1024
Listening on localhost:4567, CTRL+C to stop
$ curl http://localhost:4567/pizza?topping=extra
%20cheese
Sending you a pizza with extra cheese
In fact, you can write a _tiny_ Ruby
program using “Sinatra” that makes this
actually work:
curl is a "command-line web browser" (handwavey explanation - a
program that “speaks” HTTP and can be used in a terminal).
See the http above? We asked the local server for an unencrypted
request/response (the "request lifecycle").
See the localhost:4567? localhost is your computer (if you use a mac
or linux computer). 4567 is a "port" e.g. a place a program can be
reached by number.
The /pizza looks just like something in the program before I think!
Line 3 perhaps? That's a "route" e.g. a place in your web application
that will return something to you.
And look… the pizza service is sending you something back! I love
the future.
$ curl http://localhost:4567/pizza?topping=extra
%20cheese
Sending you a pizza with extra cheese
“Web
Frameworks”
What even is a
“Framework”?
A “framework” is, loosely speaking, a
collection of programming libraries
aimed at making your life easier in
writing a program. Every language has
them.
Some are "opinionated" e.g. they tell you
how to build programs with them e.g.
their way or the highway (Rails is that).
Some are “general”, they just want to
help somehow (Sinatra is that).
The Request/
Response Lifecycle
We have seen a “request/response
lifecycle" before.
The lifecycle is everything from the
time a browser (like curl) asks a
web-server for something until the
time it gets back and some output is
displayed (mostly).
The Request/Response
Lifecycle (con’t)
In the Sinatra example curl was run, some Gnomes
did their work (even just on your computer) until
a "web server" received the request.
A web-server's job used to be to simply shuttle files
around with Gnomes (TCP/IP and HTTP).
Now its job is to negotiate between requests and
applications which will handle those requests. Then
it can return those application's output to you, the
user. We can see that negotiation in progress…
$ curl -vv localhost:4567/pizza?topping=extra%20cheese
* Hostname was NOT found in DNS cache
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 4567 (#0)
> GET /pizza?topping=extra%20cheese HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:4567
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Connection: keep-alive
* Server thin is not blacklisted
< Server: thin
<
* Connection #0 to host localhost left intact
Sending you a pizza with extra cheese
$ curl -vv http://localhost:4567/pizza?topping=extra
%20cheese
Sending you a pizza with extra cheese
In the above we asked curl to be
verbose with -vv (very verbose).
> GET /pizza?topping=extra%20cheese HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:4567
> Accept: */*
>
Our "request" is everything starting
with a > in that big block of
response.
The Request…
> GET /pizza?topping=extra%20cheese HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:4567
> Accept: */*
>
The first line makes the request for
a pizza (with a topping) via GET
and says that we are using HTTP/1.1
(HTTP/2.0 is coming!)
The Request…
> GET /pizza?topping=extra%20cheese HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:4567
> Accept: */*
>
The next line (starting with
User-Agent) is the name and version
of the browser.
The Request…
> GET /pizza?topping=extra%20cheese HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:4567
> Accept: */*
>
The next line is the Host we are
connecting to. Some web-servers
host multiple websites so we could
also be hosting cool-cats-on-the-
internet.com on this server and the
web-server needs to send this
request to the correct application.
The Request…
> GET /pizza?topping=extra%20cheese HTTP/1.1
> User-Agent: curl/7.37.1
> Host: localhost:4567
> Accept: */*
>
The final line can mostly be
ignored right now but says that we
accept any (*/*) response type. It
could be HTML, an image, music, or
anything else.
The Request…
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< X-Frame-Options: SAMEORIGIN
< Connection: keep-alive
* Server thin is not blacklisted
< Server: thin
<
Our "response" is everything
starting with a < in the original
The Response!
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< … SNIP
<
The parts we are going to talk
about are much fewer!
The Response!
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< … SNIP
<
The first line is the most important
- It says that the response is also
an HTTP/1.1 response.
The Response!
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< … SNIP
<
200 and OK are actually the same
thing! And they are good news!
The Response!
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< … SNIP
<
200 is a "response code" e.g. a
numeric response (for computers)
saying that the request worked as
expected where the OK is the human
version of that message. Cool!
The Response!
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< … SNIP
<
The next line says that the server is
sending HTML and that it might
contain non-latin characters (that's
the utf-8 part). We said we accept
*/* so HTML should be fine.
The Response!
< HTTP/1.1 200 OK
< Content-Type: text/html;charset=utf-8
< Content-Length: 39
< … SNIP
<
After that the Content-Length tells
curl how much data to expect.
The Response!
Whew!
That is a
complete and
working web-
application…
and… an entire
request/response
lifecycle.
There’s one little
problem!
Especially since…
<HTML>
<BODY>
<p>Sending you a pizza with extra cheese</p>
</BODY>
</HTML>
What we said we were returning was
text/html but what we returned was
some text. HTML looks like this:
but we sent
Sending you a pizza with extra cheese
require 'sinatra'
get '/pizza' do
copy = if params[:topping]
topping = params[:topping]
"Sending you a pizza with #{topping}"
else
"Sending you a cheese pizza!"
end
"<HTML><BODY><p>#{copy}</p></BODY></HTML>"
end
Let's update our program to include
some HTML instead!
$ curl localhost:4567/pizza?topping=extra
%20cheese
<HTML><BODY><p>Sending you a pizza with extra
cheese</p></BODY></HTML>
And run it again…
YAY! HTML!
The next
problem….
(is not just cheesy
clip-art)
One can imagine that as your
application grows, hand rolling
(almost identical) HTML for a whole
bunch of "routes" might get tedious.
If you are building not just a pizza
delivery site but rather an Italian
restaurant site you might have
something that looks like…
require 'sinatra'
get '/pizza' do
# some code
end
get '/calzone' do
# some code
end
get '/spaghetti' do
# some code
end
get '/linguine' do
end
get '/antipasto' do
end
### the stereotypical menu may continue ad-infinitum
Paring down the
menu
One of the first things you probably want
to do is get rid of the boiler-plate HTML
and just put in the <p>#{copy}</p> for each
of those routes.
Sinatra has a convention that if a file
called views/layout.erb exists it will use it
for the boiler-plate!
Let's do that!
Create your layout
<HTML>
<BODY>
<%= yield %>
</BODY>
</HTML>
Where you see <%= yield => is where
your copy will be placed.
The above is a special templating
language called ERB that lets you
put Ruby in it!
require 'sinatra'
get '/pizza' do
copy = if params[:topping]
topping = params[:topping]
"Sending you a pizza with #{topping}"
else
"Sending you a cheese pizza!"
end
erb “<p>#{copy}</p>" # here we use the layout
end
Let's update our program to use our new
layout!
Frameworks! (con’t)
This is the beginning of the power of a framework: Sinatra
knows that if there is a file called views/layout.erb and you call
erb with a parameter, that parameter should be put in the layout
where yield is called there.
This "knowledge" is known as "Convention over Configuration".
In Sinatra (and Rails) assumptions (conventions) are made by
the framework designer. You can override them if you have a
good reason but very often you don’t have to (and shouldn’t and
that's awesome).
Conventions are also where the reputation of these frameworks
for "doing magic" comes from.
Let’s Model a thing!
We've done good work - We’ve simplified our 

/pizza route by removing some boiler-plate.
The next step might be to simplify the route by
moving the topping logic somewhere.
The reasoning here is that each route will have
some logic and it will make the original file
_really_ long.
Let's just start by moving the logic out into a Class!
require 'sinatra'
class Pizza
def initialize(topping=nil)
@topping = topping
end
def order_copy
if @topping
"Sending you a pizza with #{@topping}"
else
"Sending you a cheese pizza!"
end
end
end
get '/pizza' do
pizza = Pizza.new(params[:topping])
erb "<p>#{pizza.order_copy}</p>"
end
Yay for Models
This is awesome because now we've
made the logic in the "route" so
simple: Just build a pizza, ask it to
build its own copy, and send it back!
But that class is long so maybe we
can move it somewhere else and just
reference it here?
e.g.
Oh no!!!
I made the code LONGER!
More is Less
The lessons of Classes ond Object-
Oriented Programming
The very very very
short version
A major goal of Object-Oriented
Programming is to contain all of
the logic about a type of thing and
put it in its own isolated
description (abstraction and
encapsulation) that can be used over
and over.
But why?
Anytime we have to think about a
Pizza we look in one place: the
Pizza class definition.
Other things like Calzones or
Linguine can have their own classes
for the same reason.
So let’s make it
shorter again
Just like we put the “layout” in
views/layout.erb we can create our
own convention of putting classes
in a models/ directory.
Sinatra does not have its own
convention for models so we’re
making one to stick to!
“Extract” your
Model!
class Pizza
def initialize(topping=nil)
@topping = topping
end
def order_copy
if @topping
"Sending you a pizza with #{@topping}"
else
"Sending you a cheese pizza!"
end
end
end
models/pizza.rb
When a developer
says…
“extract” it just means cut/paste the
code from one place into another to
simplify the prior and (usually)
create the latter.
“better” they mean they have an
opinion. It is probably right or
wrong.
Use your model!
require 'sinatra'
require './models/pizza.rb'
# ^^ pull the model into our code here!
get '/pizza' do
pizza = Pizza.new(params[:topping])
erb "<p>#{pizza.order_copy}</p>"
end
We’ve Built Rails!
Sorta. Kinda. In a _really_ minimal
form.
Much segue. Such
Rails. Wow
We have now built what might be
considered a very minimal Rails
application without talking about Rails
at all!
We simply (and iteratively) used some
sane conventions to simplify one thing
at a time and put them in un-
surprising places.
That is _exactly_ how Rails came to
be.
David Heinemeier Hansson built a
Ruby web-application. Then he tore
out all of the generic stuff into his
own Framework called Rails
(warning you not to go off them!)
It exploded (into pure awesomeness)
from there.
Yeah… so show me.
(Remember slide 2?) If we had Rails
installed and typed rails new
italian_restaurant we would find a
whole bunch of files and directories
that Rails thinks we want and need.
These are the conventional files of
Rails.
Let's look at a small subset of them:
RAILS! Behold!
italian_restaurant/
app/
models/
views/
layouts/
application.html.erb
config/
routes.rb
... Many many more.
This should look
_really_ familiar!
Guess what is in app/models/ ?
Guess what is in app/views/layouts/ ?
Guess what is config/routes.rb ?
Next up…
Rails for
Reals
but you probably look
like this:

More Related Content

What's hot

神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)guregu
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Masahiro Nagano
 
Reachability in Mobile App Development
Reachability in Mobile App DevelopmentReachability in Mobile App Development
Reachability in Mobile App DevelopmentMarc Weil
 
Html5, css3, canvas, svg and webgl
Html5, css3, canvas, svg and webglHtml5, css3, canvas, svg and webgl
Html5, css3, canvas, svg and webglKilian Valkhof
 
WebShell - confoo 2011 - sean coates
WebShell - confoo 2011 - sean coatesWebShell - confoo 2011 - sean coates
WebShell - confoo 2011 - sean coatesBachkoutou Toutou
 
Building A Gem From Scratch
Building A Gem From ScratchBuilding A Gem From Scratch
Building A Gem From ScratchBrian Hogan
 
Web Scraper Shibuya.pm tech talk #8
Web Scraper Shibuya.pm tech talk #8Web Scraper Shibuya.pm tech talk #8
Web Scraper Shibuya.pm tech talk #8Tatsuhiko Miyagawa
 
PyConMY 2016 Django Channels
PyConMY 2016 Django ChannelsPyConMY 2016 Django Channels
PyConMY 2016 Django ChannelsKok Hoor Chew
 
Introduction to REST and JAX-RS
Introduction to REST and JAX-RSIntroduction to REST and JAX-RS
Introduction to REST and JAX-RSTed Pennings
 
Intro To Advanced Ruby
Intro To Advanced RubyIntro To Advanced Ruby
Intro To Advanced RubyBrian Hogan
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparisonHiroshi Nakamura
 
Scrip queue tree
Scrip queue treeScrip queue tree
Scrip queue treeMarco Arias
 
Push the web with HTML5
Push the web with HTML5Push the web with HTML5
Push the web with HTML5Stoyan Zhekov
 
Breaking The Cross Domain Barrier
Breaking The Cross Domain BarrierBreaking The Cross Domain Barrier
Breaking The Cross Domain BarrierAlex Sexton
 
PHP And Web Services: Perfect Partners
PHP And Web Services: Perfect PartnersPHP And Web Services: Perfect Partners
PHP And Web Services: Perfect PartnersLorna Mitchell
 
5. HTTP и приятели
5. HTTP и приятели5. HTTP и приятели
5. HTTP и приятелиStefan Kanev
 

What's hot (20)

Web tech 101
Web tech 101Web tech 101
Web tech 101
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7Operation Oriented Web Applications / Yokohama pm7
Operation Oriented Web Applications / Yokohama pm7
 
Reachability in Mobile App Development
Reachability in Mobile App DevelopmentReachability in Mobile App Development
Reachability in Mobile App Development
 
Transforming WebSockets
Transforming WebSocketsTransforming WebSockets
Transforming WebSockets
 
Html5, css3, canvas, svg and webgl
Html5, css3, canvas, svg and webglHtml5, css3, canvas, svg and webgl
Html5, css3, canvas, svg and webgl
 
WebShell - confoo 2011 - sean coates
WebShell - confoo 2011 - sean coatesWebShell - confoo 2011 - sean coates
WebShell - confoo 2011 - sean coates
 
Building A Gem From Scratch
Building A Gem From ScratchBuilding A Gem From Scratch
Building A Gem From Scratch
 
Web Scraper Shibuya.pm tech talk #8
Web Scraper Shibuya.pm tech talk #8Web Scraper Shibuya.pm tech talk #8
Web Scraper Shibuya.pm tech talk #8
 
PyConMY 2016 Django Channels
PyConMY 2016 Django ChannelsPyConMY 2016 Django Channels
PyConMY 2016 Django Channels
 
Introduction to REST and JAX-RS
Introduction to REST and JAX-RSIntroduction to REST and JAX-RS
Introduction to REST and JAX-RS
 
Intro To Advanced Ruby
Intro To Advanced RubyIntro To Advanced Ruby
Intro To Advanced Ruby
 
Ruby HTTP clients comparison
Ruby HTTP clients comparisonRuby HTTP clients comparison
Ruby HTTP clients comparison
 
Scrip queue tree
Scrip queue treeScrip queue tree
Scrip queue tree
 
Cors michael
Cors michaelCors michael
Cors michael
 
Push the web with HTML5
Push the web with HTML5Push the web with HTML5
Push the web with HTML5
 
Breaking The Cross Domain Barrier
Breaking The Cross Domain BarrierBreaking The Cross Domain Barrier
Breaking The Cross Domain Barrier
 
PHP And Web Services: Perfect Partners
PHP And Web Services: Perfect PartnersPHP And Web Services: Perfect Partners
PHP And Web Services: Perfect Partners
 
5. HTTP и приятели
5. HTTP и приятели5. HTTP и приятели
5. HTTP и приятели
 
Ruby HTTP clients
Ruby HTTP clientsRuby HTTP clients
Ruby HTTP clients
 

Viewers also liked

Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School
Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School
Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School Elana Jacobs
 
DigitalOceanことはじめ
DigitalOceanことはじめDigitalOceanことはじめ
DigitalOceanことはじめKohta Kunishima
 
Stampede.io CoreOS + Digital Ocean Meetup
Stampede.io CoreOS + Digital Ocean MeetupStampede.io CoreOS + Digital Ocean Meetup
Stampede.io CoreOS + Digital Ocean MeetupDarren Shepherd
 
Scaling Cloud Networking at DigitalOcean from ThousandEyes Connect
Scaling Cloud Networking at DigitalOcean from ThousandEyes ConnectScaling Cloud Networking at DigitalOcean from ThousandEyes Connect
Scaling Cloud Networking at DigitalOcean from ThousandEyes ConnectThousandEyes
 
Scaling on DigitalOcean
Scaling on DigitalOceanScaling on DigitalOcean
Scaling on DigitalOceandavid_e_worth
 
Deploying a Ruby on Rails App with Digital Ocean
Deploying a Ruby on Rails App with Digital OceanDeploying a Ruby on Rails App with Digital Ocean
Deploying a Ruby on Rails App with Digital OceanDevCo
 
The good, bad and ugly of Digital Ocean vs AWS
The good, bad and ugly of Digital Ocean vs AWSThe good, bad and ugly of Digital Ocean vs AWS
The good, bad and ugly of Digital Ocean vs AWSAzukisoft Pte Ltd
 

Viewers also liked (7)

Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School
Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School
Digital Ocean Presentation - Ruby Dev Stackup - The Flatiron School
 
DigitalOceanことはじめ
DigitalOceanことはじめDigitalOceanことはじめ
DigitalOceanことはじめ
 
Stampede.io CoreOS + Digital Ocean Meetup
Stampede.io CoreOS + Digital Ocean MeetupStampede.io CoreOS + Digital Ocean Meetup
Stampede.io CoreOS + Digital Ocean Meetup
 
Scaling Cloud Networking at DigitalOcean from ThousandEyes Connect
Scaling Cloud Networking at DigitalOcean from ThousandEyes ConnectScaling Cloud Networking at DigitalOcean from ThousandEyes Connect
Scaling Cloud Networking at DigitalOcean from ThousandEyes Connect
 
Scaling on DigitalOcean
Scaling on DigitalOceanScaling on DigitalOcean
Scaling on DigitalOcean
 
Deploying a Ruby on Rails App with Digital Ocean
Deploying a Ruby on Rails App with Digital OceanDeploying a Ruby on Rails App with Digital Ocean
Deploying a Ruby on Rails App with Digital Ocean
 
The good, bad and ugly of Digital Ocean vs AWS
The good, bad and ugly of Digital Ocean vs AWSThe good, bad and ugly of Digital Ocean vs AWS
The good, bad and ugly of Digital Ocean vs AWS
 

Similar to From zero to almost rails in about a million slides...

Socket programming with php
Socket programming with phpSocket programming with php
Socket programming with phpElizabeth Smith
 
Real-Time with Flowdock
Real-Time with FlowdockReal-Time with Flowdock
Real-Time with FlowdockFlowdock
 
Web server working
Web server workingWeb server working
Web server workingPrem Joshua
 
Wifi Security, or Descending into Depression and Drink
Wifi Security, or Descending into Depression and DrinkWifi Security, or Descending into Depression and Drink
Wifi Security, or Descending into Depression and DrinkSecurityTube.Net
 
Introduction to programming - class 8
Introduction to programming - class 8Introduction to programming - class 8
Introduction to programming - class 8Paul Brebner
 
Python tools for testing web services over HTTP
Python tools for testing web services over HTTPPython tools for testing web services over HTTP
Python tools for testing web services over HTTPMykhailo Kolesnyk
 
How does internet works
How does internet worksHow does internet works
How does internet worksRamonNavarro46
 
Crypto workshop part 1 - Web and Crypto
Crypto workshop part 1 - Web and CryptoCrypto workshop part 1 - Web and Crypto
Crypto workshop part 1 - Web and Cryptohannob
 
Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...
Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...
Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...Barney Hanlon
 
Why and How to use Onion Networking - #EMFCamp2018
Why and How to use Onion Networking - #EMFCamp2018Why and How to use Onion Networking - #EMFCamp2018
Why and How to use Onion Networking - #EMFCamp2018Alec Muffett
 
Interactive web. O rly?
Interactive web. O rly?Interactive web. O rly?
Interactive web. O rly?timbc
 
Server-Sent Events (real-time HTTP push for HTML5 browsers)
Server-Sent Events (real-time HTTP push for HTML5 browsers)Server-Sent Events (real-time HTTP push for HTML5 browsers)
Server-Sent Events (real-time HTTP push for HTML5 browsers)yay w00t
 
Sinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящееSinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящее.toster
 
node.js: Javascript's in your backend
node.js: Javascript's in your backendnode.js: Javascript's in your backend
node.js: Javascript's in your backendDavid Padbury
 
How Internet Works
How Internet WorksHow Internet Works
How Internet Workssumit kumar
 
Lec 7(HTTP Protocol)
Lec 7(HTTP Protocol)Lec 7(HTTP Protocol)
Lec 7(HTTP Protocol)maamir farooq
 

Similar to From zero to almost rails in about a million slides... (20)

Socket programming with php
Socket programming with phpSocket programming with php
Socket programming with php
 
Real-Time with Flowdock
Real-Time with FlowdockReal-Time with Flowdock
Real-Time with Flowdock
 
Web server working
Web server workingWeb server working
Web server working
 
Wifi Security, or Descending into Depression and Drink
Wifi Security, or Descending into Depression and DrinkWifi Security, or Descending into Depression and Drink
Wifi Security, or Descending into Depression and Drink
 
Kiwipycon command line
Kiwipycon command lineKiwipycon command line
Kiwipycon command line
 
Introduction to programming - class 8
Introduction to programming - class 8Introduction to programming - class 8
Introduction to programming - class 8
 
Python tools for testing web services over HTTP
Python tools for testing web services over HTTPPython tools for testing web services over HTTP
Python tools for testing web services over HTTP
 
How does internet works
How does internet worksHow does internet works
How does internet works
 
Crypto workshop part 1 - Web and Crypto
Crypto workshop part 1 - Web and CryptoCrypto workshop part 1 - Web and Crypto
Crypto workshop part 1 - Web and Crypto
 
Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...
Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...
Command & [e]Mission Control: Using Command and Event Buses to create a CQRS-...
 
Servlet & jsp
Servlet  &  jspServlet  &  jsp
Servlet & jsp
 
Why and How to use Onion Networking - #EMFCamp2018
Why and How to use Onion Networking - #EMFCamp2018Why and How to use Onion Networking - #EMFCamp2018
Why and How to use Onion Networking - #EMFCamp2018
 
Interactive web. O rly?
Interactive web. O rly?Interactive web. O rly?
Interactive web. O rly?
 
Web tcp ip
Web tcp ipWeb tcp ip
Web tcp ip
 
Server-Sent Events (real-time HTTP push for HTML5 browsers)
Server-Sent Events (real-time HTTP push for HTML5 browsers)Server-Sent Events (real-time HTTP push for HTML5 browsers)
Server-Sent Events (real-time HTTP push for HTML5 browsers)
 
Sinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящееSinatra: прошлое, будущее и настоящее
Sinatra: прошлое, будущее и настоящее
 
node.js: Javascript's in your backend
node.js: Javascript's in your backendnode.js: Javascript's in your backend
node.js: Javascript's in your backend
 
How Internet Works
How Internet WorksHow Internet Works
How Internet Works
 
The HTML5 WebSocket API
The HTML5 WebSocket APIThe HTML5 WebSocket API
The HTML5 WebSocket API
 
Lec 7(HTTP Protocol)
Lec 7(HTTP Protocol)Lec 7(HTTP Protocol)
Lec 7(HTTP Protocol)
 

From zero to almost rails in about a million slides...

  • 1. From zero to (almost) Ruby on Rails in about a million slides. e.g. How the tubes go with a dash of Ruby and almost Rails
  • 2. - Me… Paraphrasing Euclid to King Ptolemy I Soter “There is no royal road to Rails (or Geometry)”
  • 3. Ruby on Rails always seems to be taught in one fo two ways: 1. Install Ruby. Install Rails. Type rails new <project name>. 
 Type rails server and then visit http:// localhost:3000. Done. 
 
 or… 2. An introduction to “ActiveRecord”!
  • 5. The first way doesn’t teach you how to build anything in Rails!
  • 6. … The second way presumes a great deal of knowledge a new developer may not have about the web, databases, etc.
  • 8. In 1999 the web was a very simple place. A web browser loaded a "web page", a static piece of content from a "web server", whose only real job was to send files over the magic internets. A web page was not a single piece of content but rather a single HTML file that may also have some images and links in it. It also probably had some ordered or unordered lists of information, a few paragraphs, and some blinking text.
  • 9. The web today e.g. Space LASERs
  • 10. Fundamentally nothing has changed. We still have web-servers that pass files around but… lots and lots of layers of "magic" (e.g. technology) stand between those files and a user interacting with a website.
  • 11. Modern "websites" are "web applications" for the most part. The distinction between a "site" and an "application" centers around dynamic content (e.g. content that responds to your input as a user) Applications often maintain "state" that can be “persisted” e.g. there are users or accounts or pictures of cats that remember your name between visits.
  • 12. The High-Level picture! e.g. gnomes and unicorns ? ?? Browser ?
  • 13. We are not going to explain the "gnomes" in much detail here. People with titles like "network engineer" and "infrastructure engineer” make that happen. (If we want to dig into that we can do that another time) Our real goal here is to have an intuition for how unicorns (e.g. Web Applications) work in that picture.
  • 15. Gnomes are magical creatures. The internet feeds on their labor. One type of very nice Gnome is a "TCP/IP" gnome. All you need to know about them is that they work very very closely with another guild of Gnomes called “HTTP(S)" Gnomes. TCP/IP is an internet "protocol" (e.g. set of rules) for moving data around in very systematic ways.
  • 16. One type of data is HTTP(S) data. HTTP and HTTP(S) are mostly the same. The latter is encrypted where the prior is not. (Hint: “S” is for “Secure”) That's the only real difference so we will just talk about HTTP here. Everything we say about HTTP will _also_ be true of HTTP(S) only (magically) encrypted.
  • 17. A reasonable metaphor for the rest of this talk on Gnomes is that HTTP(S) gnomes hand data to the TCP/IP Gnomes (Actually, TCP and IP gnomes are two different sets of Gnomes wearing slightly different color tunics) who make sure HTTP stuff goes somewhere and gets back in the way we expect.
  • 19. HTTP(S) Gnomes HTTP is the protocol on which the web works. It stands for HyperText Transfer Protocol and is the backbone of the web. HTTP is actually a very simple protocol at first glance: HTTP defines verbs. "Web Servers" are programs that know how to interpret those verbs and the subjects they act on. The most important (e.g. fundamental) verb in HTTP is GET with which you ask a web-server to give you something e.g. a webpage or an image (or pizza).
  • 20. The High-Level picture! e.g. named gnomes and unicorns GET ?HTTP(S) Browser TCP/IP
  • 21. GET a Pizza! GET /pizza?topping=extra%20cheese Hint: %20 is a space on the internet
  • 22. require 'sinatra' get '/pizza' do if params[:topping] "Sending you a pizza with #{params[:topping]}" else "Sending you a cheese pizza!" end end In fact, you can write a _tiny_ Ruby program using “Sinatra” that makes this actually work:
  • 23. $ ruby pizza.rb == Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Thin Thin web server (v1.6.3 codename Protein Powder) Maximum connections set to 1024 Listening on localhost:4567, CTRL+C to stop $ curl http://localhost:4567/pizza?topping=extra %20cheese Sending you a pizza with extra cheese In fact, you can write a _tiny_ Ruby program using “Sinatra” that makes this actually work:
  • 24. curl is a "command-line web browser" (handwavey explanation - a program that “speaks” HTTP and can be used in a terminal). See the http above? We asked the local server for an unencrypted request/response (the "request lifecycle"). See the localhost:4567? localhost is your computer (if you use a mac or linux computer). 4567 is a "port" e.g. a place a program can be reached by number. The /pizza looks just like something in the program before I think! Line 3 perhaps? That's a "route" e.g. a place in your web application that will return something to you. And look… the pizza service is sending you something back! I love the future. $ curl http://localhost:4567/pizza?topping=extra %20cheese Sending you a pizza with extra cheese
  • 25. “Web Frameworks” What even is a “Framework”?
  • 26. A “framework” is, loosely speaking, a collection of programming libraries aimed at making your life easier in writing a program. Every language has them. Some are "opinionated" e.g. they tell you how to build programs with them e.g. their way or the highway (Rails is that). Some are “general”, they just want to help somehow (Sinatra is that).
  • 27. The Request/ Response Lifecycle We have seen a “request/response lifecycle" before. The lifecycle is everything from the time a browser (like curl) asks a web-server for something until the time it gets back and some output is displayed (mostly).
  • 28. The Request/Response Lifecycle (con’t) In the Sinatra example curl was run, some Gnomes did their work (even just on your computer) until a "web server" received the request. A web-server's job used to be to simply shuttle files around with Gnomes (TCP/IP and HTTP). Now its job is to negotiate between requests and applications which will handle those requests. Then it can return those application's output to you, the user. We can see that negotiation in progress…
  • 29. $ curl -vv localhost:4567/pizza?topping=extra%20cheese * Hostname was NOT found in DNS cache * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 4567 (#0) > GET /pizza?topping=extra%20cheese HTTP/1.1 > User-Agent: curl/7.37.1 > Host: localhost:4567 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < X-XSS-Protection: 1; mode=block < X-Content-Type-Options: nosniff < X-Frame-Options: SAMEORIGIN < Connection: keep-alive * Server thin is not blacklisted < Server: thin < * Connection #0 to host localhost left intact Sending you a pizza with extra cheese
  • 30.
  • 31. $ curl -vv http://localhost:4567/pizza?topping=extra %20cheese Sending you a pizza with extra cheese In the above we asked curl to be verbose with -vv (very verbose).
  • 32. > GET /pizza?topping=extra%20cheese HTTP/1.1 > User-Agent: curl/7.37.1 > Host: localhost:4567 > Accept: */* > Our "request" is everything starting with a > in that big block of response. The Request…
  • 33. > GET /pizza?topping=extra%20cheese HTTP/1.1 > User-Agent: curl/7.37.1 > Host: localhost:4567 > Accept: */* > The first line makes the request for a pizza (with a topping) via GET and says that we are using HTTP/1.1 (HTTP/2.0 is coming!) The Request…
  • 34. > GET /pizza?topping=extra%20cheese HTTP/1.1 > User-Agent: curl/7.37.1 > Host: localhost:4567 > Accept: */* > The next line (starting with User-Agent) is the name and version of the browser. The Request…
  • 35. > GET /pizza?topping=extra%20cheese HTTP/1.1 > User-Agent: curl/7.37.1 > Host: localhost:4567 > Accept: */* > The next line is the Host we are connecting to. Some web-servers host multiple websites so we could also be hosting cool-cats-on-the- internet.com on this server and the web-server needs to send this request to the correct application. The Request…
  • 36. > GET /pizza?topping=extra%20cheese HTTP/1.1 > User-Agent: curl/7.37.1 > Host: localhost:4567 > Accept: */* > The final line can mostly be ignored right now but says that we accept any (*/*) response type. It could be HTML, an image, music, or anything else. The Request…
  • 37. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < X-XSS-Protection: 1; mode=block < X-Content-Type-Options: nosniff < X-Frame-Options: SAMEORIGIN < Connection: keep-alive * Server thin is not blacklisted < Server: thin < Our "response" is everything starting with a < in the original The Response!
  • 38. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < … SNIP < The parts we are going to talk about are much fewer! The Response!
  • 39. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < … SNIP < The first line is the most important - It says that the response is also an HTTP/1.1 response. The Response!
  • 40. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < … SNIP < 200 and OK are actually the same thing! And they are good news! The Response!
  • 41. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < … SNIP < 200 is a "response code" e.g. a numeric response (for computers) saying that the request worked as expected where the OK is the human version of that message. Cool! The Response!
  • 42. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < … SNIP < The next line says that the server is sending HTML and that it might contain non-latin characters (that's the utf-8 part). We said we accept */* so HTML should be fine. The Response!
  • 43. < HTTP/1.1 200 OK < Content-Type: text/html;charset=utf-8 < Content-Length: 39 < … SNIP < After that the Content-Length tells curl how much data to expect. The Response!
  • 44. Whew! That is a complete and working web- application… and… an entire request/response lifecycle.
  • 46. <HTML> <BODY> <p>Sending you a pizza with extra cheese</p> </BODY> </HTML> What we said we were returning was text/html but what we returned was some text. HTML looks like this: but we sent Sending you a pizza with extra cheese
  • 47. require 'sinatra' get '/pizza' do copy = if params[:topping] topping = params[:topping] "Sending you a pizza with #{topping}" else "Sending you a cheese pizza!" end "<HTML><BODY><p>#{copy}</p></BODY></HTML>" end Let's update our program to include some HTML instead!
  • 48. $ curl localhost:4567/pizza?topping=extra %20cheese <HTML><BODY><p>Sending you a pizza with extra cheese</p></BODY></HTML> And run it again… YAY! HTML!
  • 49. The next problem…. (is not just cheesy clip-art)
  • 50. One can imagine that as your application grows, hand rolling (almost identical) HTML for a whole bunch of "routes" might get tedious. If you are building not just a pizza delivery site but rather an Italian restaurant site you might have something that looks like…
  • 51. require 'sinatra' get '/pizza' do # some code end get '/calzone' do # some code end get '/spaghetti' do # some code end get '/linguine' do end get '/antipasto' do end ### the stereotypical menu may continue ad-infinitum
  • 52. Paring down the menu One of the first things you probably want to do is get rid of the boiler-plate HTML and just put in the <p>#{copy}</p> for each of those routes. Sinatra has a convention that if a file called views/layout.erb exists it will use it for the boiler-plate! Let's do that!
  • 53. Create your layout <HTML> <BODY> <%= yield %> </BODY> </HTML> Where you see <%= yield => is where your copy will be placed. The above is a special templating language called ERB that lets you put Ruby in it!
  • 54. require 'sinatra' get '/pizza' do copy = if params[:topping] topping = params[:topping] "Sending you a pizza with #{topping}" else "Sending you a cheese pizza!" end erb “<p>#{copy}</p>" # here we use the layout end Let's update our program to use our new layout!
  • 55. Frameworks! (con’t) This is the beginning of the power of a framework: Sinatra knows that if there is a file called views/layout.erb and you call erb with a parameter, that parameter should be put in the layout where yield is called there. This "knowledge" is known as "Convention over Configuration". In Sinatra (and Rails) assumptions (conventions) are made by the framework designer. You can override them if you have a good reason but very often you don’t have to (and shouldn’t and that's awesome). Conventions are also where the reputation of these frameworks for "doing magic" comes from.
  • 56. Let’s Model a thing! We've done good work - We’ve simplified our 
 /pizza route by removing some boiler-plate. The next step might be to simplify the route by moving the topping logic somewhere. The reasoning here is that each route will have some logic and it will make the original file _really_ long. Let's just start by moving the logic out into a Class!
  • 57. require 'sinatra' class Pizza def initialize(topping=nil) @topping = topping end def order_copy if @topping "Sending you a pizza with #{@topping}" else "Sending you a cheese pizza!" end end end get '/pizza' do pizza = Pizza.new(params[:topping]) erb "<p>#{pizza.order_copy}</p>" end
  • 58. Yay for Models This is awesome because now we've made the logic in the "route" so simple: Just build a pizza, ask it to build its own copy, and send it back! But that class is long so maybe we can move it somewhere else and just reference it here?
  • 59. e.g. Oh no!!! I made the code LONGER!
  • 60. More is Less The lessons of Classes ond Object- Oriented Programming
  • 61. The very very very short version A major goal of Object-Oriented Programming is to contain all of the logic about a type of thing and put it in its own isolated description (abstraction and encapsulation) that can be used over and over.
  • 62. But why? Anytime we have to think about a Pizza we look in one place: the Pizza class definition. Other things like Calzones or Linguine can have their own classes for the same reason.
  • 63. So let’s make it shorter again Just like we put the “layout” in views/layout.erb we can create our own convention of putting classes in a models/ directory. Sinatra does not have its own convention for models so we’re making one to stick to!
  • 64. “Extract” your Model! class Pizza def initialize(topping=nil) @topping = topping end def order_copy if @topping "Sending you a pizza with #{@topping}" else "Sending you a cheese pizza!" end end end models/pizza.rb
  • 65. When a developer says… “extract” it just means cut/paste the code from one place into another to simplify the prior and (usually) create the latter. “better” they mean they have an opinion. It is probably right or wrong.
  • 66. Use your model! require 'sinatra' require './models/pizza.rb' # ^^ pull the model into our code here! get '/pizza' do pizza = Pizza.new(params[:topping]) erb "<p>#{pizza.order_copy}</p>" end
  • 67. We’ve Built Rails! Sorta. Kinda. In a _really_ minimal form.
  • 68. Much segue. Such Rails. Wow We have now built what might be considered a very minimal Rails application without talking about Rails at all! We simply (and iteratively) used some sane conventions to simplify one thing at a time and put them in un- surprising places.
  • 69. That is _exactly_ how Rails came to be. David Heinemeier Hansson built a Ruby web-application. Then he tore out all of the generic stuff into his own Framework called Rails (warning you not to go off them!) It exploded (into pure awesomeness) from there.
  • 71. (Remember slide 2?) If we had Rails installed and typed rails new italian_restaurant we would find a whole bunch of files and directories that Rails thinks we want and need. These are the conventional files of Rails. Let's look at a small subset of them:
  • 73. This should look _really_ familiar! Guess what is in app/models/ ? Guess what is in app/views/layouts/ ? Guess what is config/routes.rb ?
  • 74. Next up… Rails for Reals but you probably look like this: