Introduction To Rails

Now that you have finished learning Ruby and MVC, we have all the necessary knowledge to start coding in Rails.

Ruby on Rails is a popular framework started by DHH. Ruby on Rails stresses on the philosophy of convention over configurations. It's widely used by many companies such as Airbnb, Twitter and Github.

Rails is a perfect tool to create an API serving a web application or a mobile application. Developers have also created many Ruby libraries to assist Rails development. Some libraries are particularly designed for Rails.

To start a new project in Rails, it's amazingly easy.

$ rails new app_name

Here, app_name is a placeholder.

You will see that many files will be generated for you.

$ rails new app_name
      create
      create  README.md
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/config/manifest.js
      create  app/assets/javascripts/application.js
      create  app/assets/javascripts/cable.js
      create  app/assets/stylesheets/application.css
      ...
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
      remove  config/initializers/cors.rb
         run  bundle install
Fetching gem metadata from https://rubygems.org/
Fetching version metadata from https://rubygems.org/
Fetching dependency metadata from https://rubygems.org/
Resolving dependencies.....................
Installing rake 11.3.0
...
Using rails 5.0.0.1
Using sass-rails 5.0.6
Bundle complete! 15 Gemfile dependencies, 62 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
         run  bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted

In GUI, you will see the following folder structure with files generated by Rails.

This is what rails new does. It creates all the necessary files and folder structures in one command, so that you can start developing immediately. This is also the approach of convention over configurations, where all Rails projects will likely have the same folder structure.

There are many options for rails new. To learn about proper usage, options, descriptions and examples, you can run $ rails new --help

Usage:
rails new APP_PATH [options]

Options:
-r, [--ruby=PATH] # Path to the Ruby binary of your choice
...

Some notable options are:

  • rails new -B: Don't run bundle install
  • rails new -T: Skip test files

After you have created the project, make sure you have cd into the app's project folder. Check your current folder using $ pwd and make sure you are inside the app_name folder.

So, we are actually now ready to turn on the server because Rails is this easy to begin. Just 1 line of command to kick start.

When you run the server on your computer while you are developing, we say that we are running in development environment.

To start the server, run $ rails server or, in short, $ rails s.

~/app_name $ rails s

=> Booting Puma
=> Rails 5.0.0.1 application starting in development on http://localhost:3000
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.6.2 (ruby 2.3.1-p112), codename: Sleepy Sunday Serenity
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
Started GET "/" for ::1 at 2016-11-25 15:47:07 +0800
Processing by Rails::WelcomeController#index as HTML
 Parameters: {"internal"=>true}
 Rendering
 ...
Completed 200 OK in 34ms (Views: 15.3ms | ActiveRecord: 0.0ms)

Since the server is running inside the instance of your terminal tab, you will need to open another terminal tab if you want to run other commands.

Alternatively, if you want to shut down the server on the current tab, you can do that by doing ctrl + c in the Terminal to stop the Rails server.

So, if you see the above in your terminal, the server is already running. Reading through it, we know that we can try to access the website on http://localhost:3000, which is a local URL since your computer will be acting as both client and server.

Let's try accessing http://localhost:3000 on Chrome.

This is the welcome page by Rails. It was designed for you to see this welcome page after 1 line of command to make you feel happy. Software development can indeed be easy and fun.

Now, let's examine some of the files Rails has helped us generate and understand the pre-defined folder structure.

Gemfile

Gemfile is the place where all libraries and dependencies are defined for your applications. Libraries are codes that are written by other developers and free to use. We call them Open Source Software. We use libraries because we don't want to re-invent the wheel every time we build something. When our application depends on certain libraries to work, we call them dependencies. Most modern web applications rely on open-source libraries. To give you an example, Rails is an open-source library.

Why would someone work on software and open source it for free? Why do people make open source software?

The existing dependencies you see in Gemfile are default ones set by Rails. We call a library written in Ruby a gem. Therefore, the name Gemfile means a file of gems (or a file of Ruby libraries).

In Gemfile,

source 'https://rubygems.org'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.0.0', '>= 5.0.0.1'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.0'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'

...

group :development, :test do
  ...
end

group :development do
  ...
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Gemfile can be used in all Ruby projects, so it's not unique to Rails. You can see gem 'rails', '~> 5.0.0', '>= 5.0.0.1' where Rails is being specified as a requirement because it is essentially just a Ruby library.

The format to define a library dependency looks like this:

gem <library name>, <version>

So, what does the symbols in front of the version numbers mean?

  • >= 2.2.0 means greater or equal to version 2.2.0
  • < 3.0 means under version 3.0
  • ~> 2.2 means >= 2.2.0 and < 2.3.0

Semantic versioning boils down to:

  • PATCH 0.0.x level changes for implementation level detail changes, such as small bug fixes
  • MINOR 0.x.0 level changes for any backwards compatible API changes, such as new functionality/features
  • MAJOR x.0.0 level changes for backwards incompatible API changes, such as changes that will break existing users code if they update

Back to Gemfile, we can see that sqlite3, a relational database, will be used for database. And, puma, a web server engine, will be used as the web server.

There are different environments. The environment on your local computer is called development because it's used while you are developing. When you run automated tests, the environment is called the test environment. When you deploy your app for the world to use and access anytime, that environment is called the production environment.

Gemfile enables you to specify different gems / libraries for different environments.

config folder

Inside the config folder,

Being self-explanatory, the config folder is designed for configurations and settings for the Rails app. The folder is not meant to be frequently modified. However, there is one file inside this folder that is one of the most frequently edited file in Rails.

That file is routes.rb, which is for defining routes, where each route should include the expected URL and controller/methods the router should pass onto.

Let's see the generated routes.rb which currently has no route defined.

Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

We can try to define a route for the homepage. The homepage would be located at the path /. When a request is sent to get the homepage, the request will be passed onto the static_pages controller and handled by the index method. A homepage should be used for retrieving information, so we use the HTTP method GET.

The whole thing will look like the following:

Rails.application.routes.draw do
  # the format to define a route looks like the following:
  # <METHOD> <PATH>, to: '<CONTROLLER>#<METHOD>'
  get '/', to: 'static_pages#index'
end

Why do we use the name index for this method?

All websites are a collection of files in folders. Loading a page is essentially picking out the file you want to display in the browser then loading it. Historically, the "index" page is a list of all the webpages. We now usually call the index page the homepage.

Alternatively, if you want to define a route for creating a Tweet, you can do

Rails.application.routes.draw do
  post '/tweets', to: 'tweets#create'
end

Why "post" instead of "get"? Because the POST method is for creating data. The GET method is for retrieving data.

app folder

The app folder contains a majority of code for the MVC framework. This is where you define model, views and controllers, as you can see the folders named as models, views and controllers.

Let's try to replace the default homepage with a page that says "Hello World".

Step 1:

Make sure you have defined the route in config/routes.rb

  get '/', to: 'static_pages#index'

Step 2:

The controller static_pages doesn't exist yet. So, we should create it. To create a controller, Rails has generously provided a command to do it (yet again)!

Run

$ rails generate controller static_pages
      create  app/controllers/static_pages_controller.rb
      invoke  erb
      create    app/views/static_pages
      invoke  test_unit
      create    test/controllers/static_pages_controller_test.rb
      invoke  helper
      create    app/helpers/static_pages_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/static_pages.coffee
      invoke    scss
      create      app/assets/stylesheets/static_pages.scss

The important file we care about here is app/controllers/static_pages_controller.rb, which currently looks like

class StaticPagesController < ApplicationController
end

It's empty. So, we should define the method that matches the one we defined in the route, which is index.

class StaticPagesController < ApplicationController
  def index
  end
end

Now, in the index method, we don't need to process anything yet. We don't need to interact with the database. All we want is to render the homepage.

class StaticPagesController < ApplicationController
  def index
    # when a request comes to the route '/', it will be directed to this method
    # this is empty for now since we have nothing to process for homepage
    # so, we are going to respond with a webpage (defined in HTML)

    render 'index'
  end
end

The keyword render in a controller method means to give back a response (similar to defining the output using return for a function). render 'index' will look for the template (the View in MVC) located at app/views/static_pages/index.html.erb because Rails has this convention.

Remember, we often want to use templates when giving back a response, instead of making up on the fly, to minimize human errors.

The view file doesn't exist yet, so please create it. Inside the file, you can write "Hello World":

In app/views/static_pages/index.html.erb,

Hello World!

Done, you have just defined the response, and everything should work.

  • Start the server (if it hasn't yet)
  • Go to localhost:3000
  • The page should now say "Hello World!", instead of the default Rails homepage.

results matching ""

    No results matching ""