Ruby for Programmers – Part 17: On The ActiveRecord

This goes a little into how to run SQL. You don’t need to know everything, but this is a great tutorial on straight SQL. Good news though, you don’t have to touch any SQL for this. Here’s the tl;dr:

  • A SQL table is a lot like a spreadsheet. You have rows and columns. You should have a table for each data model.
  • Tables and their columns need to manually created and removed. When you need to make a new column, you need to manually tell the system that it needs to be created.
  • “Primary” column(s) are unique and define it. Generally speaking this is just an id number. Rails sets it up so that the database will auto increment the id so you don’t have to worry.

So let’s setup our database. We’ll be using Postgres, so we need to install it. For Macs, use It’s simple and easy. Postgres provides an installer for Windows. And Linux can use your favorite package manager.

And once it’s setup, we need a database (set of tables) to put it into. You can use the included GUI or the command “createdb” to create a database.

Then we need to install the pg gem, which might be a small issue on any machine. For example on Mac you may need to run env ARCHFLAGS="-arch x86_64" gem install pg -- --with-pg-config=/Applications/ to give it the right config file to build the C extension against. Googling eventually finds the right answer.

Hopefully now you have the gem installed, and we can run bundler with pg and ActiveRecord:

And the Railtie:

Now we need to setup the postgres password. Create a new file, config/database.yml, to put the postgres password that you used to setup the postgres root password:

Don’t forget to change the pertinent parts.

With this we can create our first migration to get the database to have the right table information. So let’s create that file:

So that’s a mouthful that’s easier explained in the Rails guide. In short this creates a table with the listed columns. By default the id primary column is create for you, as well as an automatic “created_at” and “updated_at” columns too.

To run our migration you need to run bundle exec rake db:migrate. This occurs whenever you need to run any database migrations.

And now let’s update our Page model:

Yep, it is that small. Rails is smart enough to know that the attributes is the name of the columns. It also includes a finder method and handles saving to the database for you. Of course we need to create the “create page” page since we have an empty database:

Notice how we don’t even need to create a new form? It can re-use the same form because it knows that the data is a new entry instead of an old entry and redirects accordingly.

Lastly, there’s associations, which you can read on the Rails guide. We’ll be going into associations when we start the main project, but for now the guide will do.

And that gets you up to speed with all the major parts of Rails. There’s still tons more to learn, but there’s better guides for what you need after this point:

And that’s it. This last part is available on Github.

Ruby for Programmers – Part 16: Data Models

By now we can render stuff to a webpage, which is cool, but there’s no way to make or save any data, so let’s fix that. Since we’re making a CMS thing, we’re going to need the ability to make and save data. So let’s start by making a silly flat-file data-model system in a new folder “db”:

To work with this data, we’re going to create a special class called “Page” to handle our pages. Generally speaking, any class that exclusively deals with data is called a “model”. Thus, our new file is going to be put in app/models/page.rb:

This is a bunch of code to drop, but all it really does is load a JSON file and allows you to search for data.

And let’s modify our controller and view to use the new page data:

If you just browse to “/page/page-2”, it will show the data for that page. Now that’s nice, but we can make it better.

Let’s start adding some Rails methods to the Page class to start adding some magic. We’re going to start with ActiveModel, which contains a bit of magic without requiring much more. So first let’s add it to our Gemfile:

And add it to our list of railties to preload it:

And so now we can add some specialized functions. First is ActiveModel::Model which adds some internal specialized functions:

  • ActiveModel::Naming – which creates string names from your class names. Very useful for generating routes (and table names later on).
  • ActiveModel::Translation – which automatically creates human names from the attribute name, and allows you to translate them to other languages if the translation file is available.
  • ActiveModel::Conversion – which adds a few helper functions for routing
  • ActiveModel::Validations – which we’ll get into a little bit later
  • And a few internal methods like automatically creating the initialize function for us.
  • So let’s add it:

    That’s already better, but we have no way of saving. So let’s add that:

    Admittingly, not the most optimized flat-file format but we’ll figure that out later. Now that we can edit data and have added the ActiveModel::Conversion (via Model), we can now use resources on the routes. This is just an automatic route creator that does a bunch of magic for us.

    Try a bundle exec rake routes to see what our routes looks like:

    So this creates a bunch of really common routes for us. Let’s use them. First we need a new class method called “find” that lets us find by a direct id number:

    And create a new controller:

    And our edit page:

    This takes advantage of an ActionView form builder which automatically creates the form based on attributes and fills in the default value if it exists, and routes to the correct page if the resource routing exists.

    Of course we need to create the update and show functions too:

    Here we simply see the page attributes getting updated. Now that we have the ability to edit pages, lets throw some magic in the monkey works. First, callbacks:

    You should be familiar with callbacks, and this is the same. You can define (or have defined for you), various callbacks. For instance, this touches a new “updated_at” attribute which might be useful.

    Another useful module is ActiveModel::Validation which allows one to check to see if the data validations certain conditions. For example, you may want a name or title or not be blank and have a certain minimum. For example you could do this:

    But there are built-in validators for common validations:

    The rest of the validators are on the Rails guide.

    That’s the basics of attributes and how it can modify your saving. Now let’s focus on databases.

    As always, code examples are on Github.

Ruby for Programmers – Part 15: Action Packed Viewing

So as I mentioned in the last part of rendered, we built a fairly simple rendering engine using Rails’ built-in templating engine ERB. And that’s fine, but there’s still a lot of code in our controllers and Rails has a full featured rendering system called ActionView, which not only includes the rendering methods but tons of helpers to build pre-filled forms, etc.

So first let’s add ActionView to our Gemfile:

And after a bundle install, ActionView is available. It also adds the “erubis” gem, which is better, safer, and faster ERB handling than the simple built-in ERB handler.

We’re also going to add the railtie to our application.rb just so that ActionView has access to the various Rails configuration files:

And lastly, add the renderer to our controller:

In a Metal, you need to define where the views are location, such the line in #18. But notice that we got rid of all that rendering code. And our pages now render!

Going over all the different helpers would take far too long, so I’m just going to mention them as I get into them. The Guide on Form Helpers is a better resource. However, there is a couple of big notes to add:

First, HTML safety. Nasty insertable HTML and Javascript to steal your cookies and delete your pages is everywhere, so we don’t want to trust anything from the database. So every String that passes through ActionView is sanitized unless it’s marked as safe. So for example, if we change our @hi variable to @hi = '


', then what gets outputted in our index is: Front Page! <h1>sup</h1> It actually will convert so that it displays the HTML. This is a safety first option, but if for some reason you can trust the output, then you can use #.html_safe in the ERB to mark as safe:

This marks it as safe to straight output vs. sanitizing.

And secondly, layouts! Should be obviously useful as any webpage has the same headers and footers, so let’s render the inside from the outside. To enable, just change to ActionView::Layouts:

And you’re good to go. While you can use the ActionController#layout method to define custom layouts, by default it uses the name of the controller to use as a layout. (If a layout doesn’t exist, then it will just render straight pages.) You put layouts in the app/views/layouts folder, separate from the controller views.

So let’s make a really simple layout:

And that’s it! With the magic filename, you have included a layout. Note that for layouts to render their insides, you must include a yield, which returns the inside of the layout.

Just to finalize things up, we’re going to set the controller to ActionController::Base now:

ActionController::Base is nothing but the Metal, but with all the batteries included. So it includes ALL the modules (and more!) that we’ve mentioned, preloads the view paths, and all that good stuff.

And just as a small detail, most Rails apps don’t have their controllers from the Base, but include an ApplicationController and use a hierarchical format:

Because of hierarchy, this allows the filters to act for all inherited controllers, and is typically a good idea to have all controllers inherit from this.

And that’s ActionController. We have now built a very, very fancy method of generating webpages, but there’s no meat here. We’ll be going over the basics of the form generation soon, but to do that, we need something to save against, so we’ll be working next on persistence.

If you want to get ahead in the next few lessons, read up on the basics of SQL commands. (We’ll eventually be using Postgres for this project.) However, unlike HTML where you need to know the basic tags and such, you technically don’t need to know anything about SQL since Rails/ActiveRecord completely abstracts it out. However, it’s good to know that the abstraction is just a fancy SQL generator, so knowing why it works gets a leg up.

As always, working code is available here:

Ruby for Programmers – Part 14: ERB My HTML!

And now for something completely different.

Let’s say you want to generate some HTML. Using interpolated strings is generally not a good idea as it can lead to unmaintainable code. The best way to handle this is through a templating engine, which is output text intermixed with code. Thankfully, Ruby itself contains it’s own built-in templating engine: ERB

‘binding’ is a special variable that is an object that contains the current variable scope. Yes, even scopes are objects that you can pass around. (Not recommended outside of template engines, as it messes with the garbage collector and may lead to memory leaks.)

There are three different tags to invoke:

The first allows one to write code before, and around, text. The second puts the result of code in the the output itself. The last is a way to write a comment. (You do write comments don’t you?)

So let’s add erb to our controller:

But that doesn’t really abstract that out enough to be useful. However, we can now put the text into different files, which is even better! We’re going to put the views into app/views/CONTROLLERNAME/ACTIONNAME.html.erb :

So as you can see in the controller, we’re pretty much doing the same thing, which means abstraction time and another new module: ActionController::ImplicitRender, which simply calls #render after the method is run:

And let’s add some more programmability with that:

This lets us pass some options and force a different type of render if we so please. In this case, it lets us give a specialized 404 error if the page id isn’t what we expect. You can render a text value and a status. But what if we wanted to render a different layout? Well all that, and more, is in the ActionView, a culmination of all the rendering points and more, in the next part.

As usual, working code examples are in my Github:

Ruby for Programmers – Meta 1: HTML

Just in case you’re following from the blog, the next few parts will involve HTML rendering. Since these lessons are about Ruby / Rails, I’m going to assume that you know how to write HTML by hand, since we’ll be introducing a lot of magic functions that create HTML for you. If you don’t know how to HTML, Shay Howe wrote a wonderful HTML tutorial, which is available on his website.

Shay’s tutorial goes into box models and typography early on, which is important for creating custom pages. But, I will be using Bootstrap as the default CSS theme for this tutorial. So instead of writing my own box models and typography CSS, I’ll be using Bootstrap’s CSS and HTML prescriptions.

Ruby for Programmers – Part 13: Revving Some Metal

Earlier we had put together a basic controller and used the Routing and Metal to render some basic pages, but since we’re going to build a simple Generic Content Manager out of this, the parameters seem important. The method in which we got that information was out of a weird quirk of information that was automatically included in the env variable that was passed around. However, there’s better ways to get this.

This isn’t a module but just automatically included in Metal that I forgot in the last part. The params variable holds all the parameters that was sent to the page, including the GET parameters, POST parameters, and parameters set by the routing:

We’re also going to add Instrumentation to the controller too. This adds tons more useful logging like page benchmarks and displays all the parameters. We also need to make a small change to our application.rb file too:

This adds the ActionController ‘railtie’, which adds useful information to the class like where the Rails log is, ability to have a config information in the config/environments folder, and the like. Don’t forget to restart your app, and you’ll notice more logging information on each page load. Cool:

What page and how long it took and what parameters, all useful information.

Rescue lets you create custom rescuables in case something goes wrong:

Pretty simple, this detects a Ruby Exception (or a subclass of Exception) and lets you render a special page from a specially defined method. In this basic example, I divided by zero accidentally in my code and rescued from that error. I should note that this is controller-wide, mostly as a last-ditch failsafe to render a decent 500 or 404 error to a user rather than the built-in HTML files.

Redirecting just creates a simple #redirect_to function that creates all the HTTP parts necessary to redirect a browser to a different page. (For the SEOers in the crowd, by default it’s a 302 Found or temporary redirect, you can set it to 301 Moved Permanently or 303 Other if you so desire.)

UrlFor is a special class that helps you create URLs from your list of routes and the current route you are using. Note in the above it says :action=>:show, :id=>”butts”, (which I’m unsure why I used the older hash rocket style, but it’s a habit). In that case, it doesn’t define a controller so the UrlFor assumes that the controller is the one that I’m on. If you use redirect_to :id=>”butts2″ while in the #show action, then it’s the same as redirect_to :controller=>”mainpage”, :action=>”show”, :id=>”butts2″ since it will assume the same route elements for the ones that are missing. Very useful for dynamic URL making.

There’s a few more modules we could add, but it’s better to look at the code and read about it since those are more “as you need it”:

  • HttpAuthentication: Allows you to set a HTTP user/password system managed by Rails (vs. being managed by the HTTP server or forwarder)
  • DataStreaming: Allows you to send files to the browser, either hosted and read directly by the forwarder, sent directly to Rack as a large string, or create dynamically generated files to force the browser to download (such as CSV files).
  • Streaming: A still-in-progress addition that allows one to render partials of a page. For example, render the top part with the CSS and Javascript, send that to the browser to chew on early, then render the rest of the page to send to the browser. Still requires lots of specialized support (ie. most middlewares and servers don’t support it), but pretty cool if it all fits together.
  • ForceSSL: A simple helper that enforces page loads over SSL and redirects if not on SSL. Useful for password pages and such.
  • Cookies: (actual documentation here), Simple cookie handling if for some reason you need tons of random cookies. (Note that we’ll be using Rail’s built-in session management to handle cookies for us, so you don’t explicitly need this. This is only if you want raw cookie access)
  • ConditionalGet: This handles HTTP caching on the user’s browser side. For example, you can tell a browser to keep a copy on a user’s computer and not download, thus saving time and bandwidth.

That’s some of the magic functions and defaults available to a Controller. As you can see, these functions mostly just get and set various HTTP information for you. Next time, we’ll be rendering. No longer will the view data be in the in controller, we’ll put that into it’s own file with it’s own logic. Yay! (Also Session Management to store data in cookies.)

As usual, working code for this part is available here:

Ruby for Programmers – Part 12: Totally Metal

Earlier, we briefly went over the controller as a way to store the methods of routes, but there’s way more to it then returning a bunch of status codes and headers. So now we’re going to add another piece of the pie, the ActionController, which is actually three different classes in increasing complexity, the AbstractController, the Metal, and the ActionController.

The AbstractController::Base just contains a base set of functions and modules that help out. Normally one wouldn’t make an AbstractController::Base, but this is just for show. So here’s our AbstractController:

So that doesn’t look much different then before. We still have to make our own self.action method. But we now have access to a few cool built-ins, the most important of which is the callback:

What it does, is allows a function to operate before all functions. On both pages, @hi is set. This is useful for tons of things like session management, page view counts, etc.

But, we still have to do that goofy array, so let’s get rid of it… with Metal. \__/

The ActionController Metal the base class that simply does what we already do with the array format and the action handle, but adds some sprinkles to make it look better. It’s only 235 lines long and doesn’t include much fluff.

So here’s our totally Metal controller:

All the Metal really does is abstract out the env and the array, and also by default sets the content-type to ‘text/html’. Which is still a bonus because this controller is now starting to look good. It’s got some basic includes at the top, and just responds with basic text. At this point, all we did was abstract out the basics even more. Outside of including modules (like the Callback), the Metal is just a fancier version of our starting basic controller that’s not part of any class.

The Metal alone is perfectly serviceable, and some people prefer to use it. History lesson: the Rails Metal comes from the merge of Rails and Merb, where Merb was a from-the-ground-up system with plugins like I’m showing here.

Since we’re (mostly) done with abstracting out how to build a webpage, the next few segments will focus on the ‘batteries included’ part of Rails.

A couple of extra notes about callbacks, first you can limit the callback, or even skip the callback, to specific functions. Just add the array of the functions:

Skipping filters is useful for hierarchical class inheritance.

Also, when a callback returns with a response_body (or renders or redirects as we’ll see later), it skips the rest of the call stream. For example this:

Would always render “mystery callback” onto a page and never even run the #index or #show functions. This is another useful thing to be mindful of, and yet another powerful feature. For example, if you want to enforce a user login, then all you have to do is check if the user is logged in, and if not, redirect them to the login page. It will both not run the code they cannot use (since they are not logged in) and it will redirect them to a page where they can login. Useful!

Ruby for Programmers – Part 11: Railtying It Together

Having all this on one script is okay for now, but it’s best to start splitting up files just to make it easier to follow. So let’s create some folder conventions for us:

  • app/controllers will contain our controllers as determined by our routes
  • config/routes.rb will contain the routes drawer
  • config/boot.rb will contain the boot script
  • config/application.rb will contain information specific to our application, and hold information between files.
  • config/environment.rb will have the initializers after our application.
  • public/ will contain public files like CSS or error files

So first in boot.rb we’ll put the require ‘bundler/setup’. Since it’s in another folder, we’re going to need to tell that the file is in another castle:

ENV is a sweet built-in Ruby variable that contains the shell environment variables. This is useful if you want to store different configurations for different setups. Instead of different that may or may not be uploaded, it’s far better to store this information in an environment variable. You can setup this on the server so as to hide passwords or API keys too.

Below that is a really short version of the Rails application initializer. So we created a Rails module (for now think of modules as function containers), and made it so that Rails.application is accessible from anywhere. We then created a class named Application and used a Ruby auto-function named “inherited” where if a new class is made, it will run that function. In this case it sets Rails.application to a new instance of the child class. (If you’re confused, don’t worry, this is all automagicked away soon).

We also create the routes and the routes file:

Which is just a copy/paste of our original routes. Note that it uses our Rails.application that was created, which means we need to create the child class to be inherited and instanced:

Pretty boring here except this is where we create the class to be inherited. It also requires the boot file and mainpage_controller.rb file here too. mainpage_controller.rb itself is just a copy/paste:

Exactly like the old one.

For now, our environment.rb will just include the application and the routes file:

And will just include the environment.rb and run the routes:

This boots and shows the same stuff as before with our routes.

You can view the working example here:

Now before I go, there’s a reason why all this moving around, it’s just to show how Rails ties things together. In fact, the gem that holds all this together is “railties”. So let’s add it to our Gemfile, and update our scripts to use it:

And run bundle install. Now we only need to make a few small changes to a few files. boot.rb will get it’s Rails stuff removed since it’s now handled in the railties gem:

environment.rb now tells Rails to initialize (which will auto-load important files like routes.rb):

And will run Rails.application instead of the routes, since Rails will handle some automagic for us:

Since railties will automatically load the controller files for us, we just need to make a couple small modifications to our application.rb file:

We tell it to look for Rails and ActionController (which is next lesson, but railties/routing was whiny without it). Also, we started on the config because Rails complained without it.

And it works. bundle exec rackup will boot your app and it will still work like before, but now running on Rails. Once you load, you’ll notice it whining about eager_loading, so lets add an environment file config/environments/development.rb:

You can ignore the actual settings until we need to go for them. However, this file is important because it defines some of the eager loading that makes Rails great. We’ll also add the default Rakefile too, while we’re at it.

Now you can run the app a different way bundle exec rails server. This boots the server a different way, but has all trimmings. rackup still works, but the rails server has better logging and debug files.

So this lesson just really moved things around, which is nice. But the controllers are still using the weird array output and a bad way to create HTML. So next lesson, let’s add some ActionControllers with some ActionViews.

The final code for this part is here:

Ruby for Programmers – Part 10: Actionpacked Routing!

So as we saw in the last part, having different pages might end up being a slight pain, so let’s add some routing. First we’re going to need the actionpack gem, so lets add that to our Gemfile:

Note that we’re going to be using the latest beta version because by the time this is done, the new version will be out. 😛

Run bundle install to install your new gem.

Woah, that’s a lot of dependencies! We’ll eventually get to them as needed. But for now, we’re just going to include the routing part.

The allows the use of Middleware, or something that’s run before your app. So if you wish to use a something that automates something before every page call, such as routing, then you can make a Middleware. For a simple example, look at what happens when there’s an error in your code:

Load that in your browser via bundle exec rackup. It will show the default Rack error page. But what if you want a fancier page? There’s a middleware for that: ActionDispatch::ShowExceptions . It will allow us to show webpages to status errors so that the end-user doesn’t see code errors. It’s real simple to add, first add the files to a new folder “public”, and individual status codes like so:

Screen Shot 2014-01-05 at 6.03.08 PM

You can get the HTML for those pages in the public example on Github.

Why is the folder called “public”? Because I said so. (It’s a Rails convention actually.)

Then add the following to your

The new line means to use the middleware ActionDispatch::ShowExceptions, with the argument of ““public/”)”. In this case, ActionDispatch::ShowExceptions requires a secondary middleware to route to actually show the exception. The “public/” of course means to look for any files in our newly created public folder.

Then load your front page. It should now have a prettier error page:

Screen Shot 2014-01-05 at 6.05.41 PM

It’s the little things that count.

So lets add some routing, so here’s our updated file:

So let’s go over what we did. First, we created a new RouteSet, which is fine, and then started to draw some routes. Notice how the routes mention a “mainpage#index” or “mainpage#show”? It means that to route that to a MainpageController#index or MainpageController#show action. Why does it add Controller to the class name? Because I say so.

On the MainpageController is a self.action handler to handle the route internals by creating a new instance. And the individual methods now look like before with the status, header, body like in the other example.

Towards the end we add ActionDispatch::DebugExceptions to show the errors in the log in our terminal, because errors are now hidden from the browser. And finally, our app is no longer a function but rather the routes we created (which will forward to it’s respective controller).

Anyway, the routes are exactly like Rails routes, so a better documentation was written in the Rails Guide. There is some fancy pants stuff other than generating each individual route, like “namespace” which allows you to create namespaced controllers (like Admin::PostController for an admin interface), “resources” which creates the standard routes for an object (index, show, new, edit, create, update, destroy), and constraints by regex, subdomain, and more.

We’ll be going over the part of routes we’ll be adding as we add them. This just shows how routes fits in the whole scheme.

Download the working example code here:

Ruby for Programmers – Part 9: Making Pages With Bundler and Rack

So ends the really basic tutorial. There’s still tons more stuff to go over, like Modules and Mixins, Monkeypatching, Begin/Rescue/Ensure, but we’ll get to those basics as we come to them. If you really want to learn some deep dark mysteries, I suggest reading the Pickaxe Book. It’s a complete, unabridged, and also includes information about the standard library too.

So for now, we’re going to focus on creating a web app with Rails. There are other Ruby-based frameworks like Sinatra, we’re going to be focusing on Rails since it’s got, at least in my opinion, the right amount automagic for what we’re going to build. (Of course one could argue that Node or Java or some other language would be better. That’s not the scope of this, but to learn Rails.)

I’ve always found it better to learn Rails from the ground-up from its parts rather than a “here’s all the random things it can do!” that’s in most docs/tutorials. So to build a webpage from scratch, you must first invent the universe.

In which case, you must start with a Gemfile and Bundler. In the dayes of olde, gems were not included with Ruby, but rather a separate installation. These days, it’s included with the Ruby source as part of a standard installation. However, what’s missing is a package version manager, which is Bundler. You can install bundler as you would any other gem:

Bundler ensures that everybody is running the same version of gem as you, which is very important as APIs and functions changes, and helps ensure security updates by listing gem versions.

So for now, we’re going to create a Gemfile in our project and list Rack as a gem:

Bundler allows a bunch of configuration options in the Gemfile (which can be read in the Bundler docs). To note the current lines, the first tells Bundler to enforce a Ruby version. This is slightly helpful if you have a custom installation on a server, but especially helpful on cloud services like Heroku which otherwise wouldn’t know which Ruby version to use. (You don’t automatically want to use the latest and greatest because it might introduce bugs.) The second determines where the gems will download from (always Then list the gems by name, and optionally by version. You can do the normal >, >=, <, <= tags, but ~> is special. It means that “incrementing the last number is okay, but not the others”. In this case Bundler can safely install 1.5.2, 1.5.3, 1.5.1052, but not 1.6.0. Also note that when installing on a server, Bundler will install the exact gem version you have from the Gemfile.lock file.

To install your gems just run bundle install from where your Gemfile is. This will create the Gemfile.lock which will tell servers and other programmers which version to use. If you’re missing a version, running bundle install will install it. If you wish to change a version, update the Gemfile and run bundle update rack or whatever the name of the gem to update. This will re-run the dependency check and put the new version in.

Once you have Rack installed, now it’s time to use it. While Rack can be called from a method like anything else, Rack apps typically have a “” file which is just a special file it looks for to operate.

So to create our first Rack app, just insert the following into a new file:

The first two lines tells Ruby to include rubygems, a holdover from the previously said days where gems is not included but good to do anyway. The second runs the Gemfile and includes all of its requested gems. Then we tell Rack to run a very simple app, which is already returned as an array with three elements: the HTTP status code (200 for page info, 404 for not found, etc.), the headers in a Hash, then the body of the response. Note that the body of the response has to respond to #each for metaprogramming and lazy-loading reasons we’ll go over later. Just for now, let’s make it a single element Array with a String.

To run your app, just run bundle exec rackup on the command line. (Bundle also ensures that you run the right version from the command line too, how nice!) Then just open your browser to localhost:9292 (or whichever port it chooses), and your page now loads! Nice, neat, easy simple. Except that every page is the same. Lets view what’s in the env variable:

Quit your app and restart to load new code. Reload the page to view all kinds of wonderful information:

So from here we can get the path requested and do things if we wanted to, like this:

It’s not pretty, but it does either show front page if you go to http://localhost:9292/ and a 404 error if you go to http://localhost:9292/asdf.

So right here off the bat, it’s going to show lots of things that are different if you are coming from a generic PHP side of things. PHP is generally a server plugin that operates based on which file is being requested. Even if you’re doing mod_rewrite stuff, it still generally just requests a file. Any changes to the file is fine, as the script is run on each page load.

Here though, it’s an app in the background that accepts a real HTTP connection. The app has to be running and any changes requires a restart of the app. It’s more of a tradeoff though: Large apps can keep it’s compiled code in memory and respond quicker vs. parsing scripting on each page load. For Ruby, since the code parsing for large apps is fairly slow, the server model is used.

Not all is lost, you can simply put your app behind a reverse proxy (Apache instructions, Nginx instructions). Now using straight Rackup and WEBrick (Ruby’s included web server in ruby) is not a good idea on the deploy-side. There’s better options for those that run your own servers, like Unicorn, Puma, Passenger, the latter available in both open-source and enterprise editions, and Heroku, Docker, and AWS Beanstalk on the cloud-side. We’ll be mostly focusing on app building rather than deployment for the most part.