Instructor Michael Hartl walks through the beginning stages of developing a professional-grade sample application with Ruby on Rails, specifically the creation of static pages.
In this chapter, we will begin developing the professional-grade sample application that will serve as our example throughout the rest of this tutorial. Although the sample app will eventually have users, microposts, and a full login and authentication framework, we will begin with a seemingly limited topic: the creation of static pages. Despite its apparent simplicity, making static pages is a highly instructive exercise, rich in implications—a perfect start for our nascent application.
Although Rails is designed for making database-backed dynamic websites, it also excels at making the kind of static pages we might create using raw HTML files. In fact, using Rails even for static pages yields a distinct advantage: we can easily add just a small amount of dynamic content. In this chapter we’ll learn how. Along the way, we’ll get our first taste of automated testing, which will help us be more confident that our code is correct. Moreover, having a good test suite will allow us to refactor our code with confidence, changing its form without changing its function.
3.1 Sample App Setup
As in Chapter 2, before getting started we need to create a new Rails project, this time called sample_app, as shown in Listing 3.1.1
Listing 3.1: Generating a new sample app.
$ cd ˜/workspace $ rails _5.0.0_ new sample_app $ cd sample_app/
(As in Section 2.1, note that users of the cloud IDE can create this project in the same workspace as the applications from the previous two chapters. It is not necessary to create a new workspace.)
Note: For convenience, a reference implementation of the completed Rails Tutorial sample app is available at Bitbucket.2
As in Section 2.1, our next step is to use a text editor to update the Gemfile with the gems needed by our application. Listing 3.2 is identical to Listing 1.5 and Listing 2.1 apart from the gems in the test group, which are needed for the optional advanced testing setup (Section 3.6) and integration testing starting in Section 5.3.4. Note: If you would like to install all the gems needed for the sample application, you should use the code in Listing 13.72 at this time. Important note: For all the Gemfiles in this book, you should use the version numbers listed at gemfiles-4th-ed.railstutorial.org instead of the ones listed below (although they should be identical if you are reading this online).
Listing 3.2: A Gemfile for the sample app.
source 'https://rubygems.org' gem 'rails', '5.0.0' gem 'puma', '3.4.0' gem 'sass-rails', '5.0.5' gem 'uglifier', '3.0.0' gem 'coffee-rails', '4.2.1' gem 'jquery-rails', '4.1.1' gem 'turbolinks', '5.0.0' gem 'jbuilder', '2.4.1' group :development, :test do gem 'sqlite3', '1.3.11' gem 'byebug', '9.0.0', platform: :mri end group :development do gem 'web-console', '3.1.1' gem 'listen', '3.0.8' gem 'spring', '1.7.2' gem 'spring-watcher-listen', '2.0.0' end group :test do gem 'rails-controller-testing', '0.1.1' gem 'minitest-reporters', '1.1.9' gem 'guard', '2.13.0' gem 'guard-minitest', '2.4.4' end group :production do gem 'pg', '0.18.4' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
As in the previous two chapters, we run bundle install to install and include the gems specified in the Gemfile, while skipping the installation of production gems using the option --without production:3
$ bundle install --without production
This arranges to skip the pg gem for PostgreSQL in development and use SQLite for development and testing. Heroku recommends against using different databases in development and production, but for the sample application it won’t make any difference, and SQLite is much easier than PostgreSQL to install and configure locally.4 In case you’ve previously installed a version of a gem (such as Rails itself) other than the one specified by the Gemfile, it’s a good idea to update the gems with bundle update to make sure the versions match:
$ bundle update
With that, all we have left is to initialize the Git repository:
$ git init $ git add -A $ git commit -m "Initialize repository"
As with the first application, I suggest updating the README file to be more helpful and descriptive by replacing the default contents of README.md with the Markdown shown in Listing 3.3. Note that the README includes instructions for getting started with the application. (We won’t actually need to run rails db:migrate until Chapter 6, but it does no harm to include it now.)
Listing 3.3: An improved README file for the sample app.
# Ruby on Rails Tutorial sample application This is the sample application for [*Ruby on Rails Tutorial: Learn Web Development with Rails*](http://www.railstutorial.org/) by [Michael Hartl](http://www.michaelhartl.com/). ## License All source code in the [Ruby on Rails Tutorial](http://railstutorial.org/) is available jointly under the MIT License and the Beerware License. See [LICENSE.md](LICENSE.md) for details. ## Getting started To get started with the app, clone the repo and then install the needed gems: ``` $ bundle install --without production ``` Next, migrate the database: ``` $ rails db:migrate ``` Finally, run the test suite to verify that everything is working correctly: ``` $ rails test ``` If the test suite passes, you'll be ready to run the app in a local server: ``` $ rails server ``` For more information, see the [*Ruby on Rails Tutorial* book](http://www.railstutorial.org/book).
Then commit the changes as follows:
$ git commit -am "Improve the README"
You may recall from Section 1.4.4 that we used the Git command git commit -a -m "Message", with flags for “all changes” (-a) and a message (-m). As shown in the second command above, Git also lets us roll the two flags into one using git commit -am "Message".
Since we’ll be using this sample app throughout the rest of the book, it’s a good idea to create a new repository at Bitbucket and push it up:
$ git remote add origin email@example.com:<username>/sample_app.git $ git push -u origin --all # pushes up the repo and its refs for the first time
To avoid integration headaches later on, it’s also a good idea to deploy the app to Heroku even at this early stage. As in Chapter 1 and Chapter 2, I suggest following the “hello, world!” steps in Listing 3.4 and Listing 3.5. (The main reason for this is that the default Rails page typically breaks at Heroku, which makes it hard to tell if the deployment was successful or not.)
Listing 3.4: Adding a hello action to the Application controller.
class ApplicationController < ActionController::Base protect_from_forgery with: :exception def hello render text: "hello, world!" end end
Listing 3.5: Setting the root route.
Rails.application.routes.draw do root 'application#hello' end
Then commit the changes and push up to Bitbucket and Heroku:
$ git commit -am "Add hello" $ git push $ heroku create $ git push heroku master
As in Section 1.5, you may see some warning messages, which you should ignore for now. We’ll deal with them in Section 7.5. Apart from the address of the Heroku app, the result should be the same as in Figure 1.19.
As you proceed through the rest of the book, I recommend pushing and deploying the application regularly, which automatically makes remote backups and lets you catch any production errors as soon as possible. If you run into problems at Heroku, make sure to take a look at the production logs to try to diagnose the problem:
$ heroku logs
Note: If you do end up using Heroku for a real-life application, be sure to follow the production webserver configuration in Section 7.5.
Solutions to exercises are available for free at railstutorial.org/aw-solutions with any Rails Tutorial purchase. To see other people’s answers and to record your own, join the Learn Enough Society at learnenough.com/society.
Confirm that Bitbucket renders the Markdown for the README in Listing 3.3 as HTML.
By visiting the root route on the production server, verify that the deployment to Heroku succeeded.