Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

353 views

Published on

A presentation explaining the web with zero background aimed at brand new developers wanting to build Ruby on Rails applications but not knowing where to start

Published in: Internet
  • Be the first to comment

  • Be the first to like this

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

  1. 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. 2. - Me… Paraphrasing Euclid to King Ptolemy I Soter “There is no royal road to Rails (or Geometry)”
  3. 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”!
  4. 4. NOPE!
  5. 5. The first way doesn’t teach you how to build anything in Rails!
  6. 6. … The second way presumes a great deal of knowledge a new developer may not have about the web, databases, etc.
  7. 7. The Web Circa 1999
  8. 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. 9. The web today e.g. Space LASERs
  10. 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. 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. 12. The High-Level picture! e.g. gnomes and unicorns ? ?? Browser ?
  13. 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.
  14. 14. GNOMES! e.g. HTTP(S)
  15. 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. 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. 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.
  18. 18. HTTP(S) Gnomes!
  19. 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. 20. The High-Level picture! e.g. named gnomes and unicorns GET ?HTTP(S) Browser TCP/IP
  21. 21. GET a Pizza! GET /pizza?topping=extra%20cheese Hint: %20 is a space on the internet
  22. 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. 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. 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. 25. “Web Frameworks” What even is a “Framework”?
  26. 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. 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. 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. 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. 30. $ 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).
  31. 31. > 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…
  32. 32. > 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…
  33. 33. > 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…
  34. 34. > 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…
  35. 35. > 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…
  36. 36. < 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!
  37. 37. < 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!
  38. 38. < 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!
  39. 39. < 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!
  40. 40. < 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!
  41. 41. < 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!
  42. 42. < 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!
  43. 43. Whew! That is a complete and working web- application… and… an entire request/response lifecycle.
  44. 44. There’s one little problem! Especially since…
  45. 45. <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
  46. 46. 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!
  47. 47. $ 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!
  48. 48. The next problem…. (is not just cheesy clip-art)
  49. 49. 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…
  50. 50. 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
  51. 51. 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!
  52. 52. 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!
  53. 53. 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!
  54. 54. 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.
  55. 55. 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!
  56. 56. 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
  57. 57. 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?
  58. 58. e.g. Oh no!!! I made the code LONGER!
  59. 59. More is Less The lessons of Classes ond Object- Oriented Programming
  60. 60. 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.
  61. 61. 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.
  62. 62. 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!
  63. 63. “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
  64. 64. 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.
  65. 65. 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
  66. 66. We’ve Built Rails! Sorta. Kinda. In a _really_ minimal form.
  67. 67. 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.
  68. 68. 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.
  69. 69. Yeah… so show me.
  70. 70. (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:
  71. 71. RAILS! Behold! italian_restaurant/ app/ models/ views/ layouts/ application.html.erb config/ routes.rb ... Many many more.
  72. 72. This should look _really_ familiar! Guess what is in app/models/ ? Guess what is in app/views/layouts/ ? Guess what is config/routes.rb ?
  73. 73. Next up… Rails for Reals but you probably look like this:

×