Skip to content

Instantly share code, notes, and snippets.

@ptMcGit
Last active December 12, 2016 03:57
Show Gist options
  • Save ptMcGit/0e9a9ffa79d554197ecc76065c84306f to your computer and use it in GitHub Desktop.
Save ptMcGit/0e9a9ffa79d554197ecc76065c84306f to your computer and use it in GitHub Desktop.
A Brief and Incomplete Rails Tutorial for Mac OS X

Ruby on Rails Tutorial for Mac

http://edgeguides.rubyonrails.org/ - main documentation

Ruby on Rails is a web application framework built using Ruby.

Some of the code is straight Ruby, and some of it is a domain specific language for rails i.e. code that is meant to be used in a Rails web application, and might not work as expected in a Ruby script.

Ruby Language

http://ruby-doc.org/ - main documentation

  • strives to be elegant and easier to read
  • object-oriented programming
  • a lot of functionality out of the box, and added functionality through gems

Gems

http://guides.rubygems.org/rubygems-basics/ - main documentation

Bundler is used to manage ruby gems in Rails apps.

http://bundler.io/

The fact is that a Rails app has 3 environments: test, development, and production.

In essence, you can have gems installed on your machine and gems that are not.

This can be a source of confusion, particularly in the context of gems i.e. you may have a gem that is used in only 1 environment, 2 environments, or all environments.

Thankfully, this won't be a source of major snags, and good help is readily available on the web.

Note that you can always check which environment you are in with the following:

puts ENV['RAILS_ENV']

Ruby on Rails Installation On Mac

http://installrails.com/ - this is pretty good in terms of what we'll need.

A summary version of the above link:

  1. Xcode - find it in the app store.
  2. Homebrew - this is great for finding developer tools built for mac, use brew search to find stuff like emacs.
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`

Verify:

brew -v

Make sure brew is ok:

brew doctor
  1. Git
brew install git
  1. RVM - manage different versions of Ruby

Install:

curl -L https://get.rvm.io | bash -s stable

Close terminal, and see if loaded properly:

rvm | head -n 1

Now install ruby:

rvm use ruby --install --default
  1. Ruby On Rails
gem install rails --no-ri --no-rdoc

Verify:

rails --version

First Rails App

Rails allows you to perform many operations in large detail or small detail. Much of the "macro-work" aka "scaffolding" can be done from the command-line.

To create a new rails app:

NOTE: you may want to create an app that uses postgresql as the db instead (Rails currently defaults to sqlite)... see discussion in "More On Databases"

rails new my_app

This creates a new folder called containing everything your app needs.

We can start our rails server (preferably in another terminal, or in the background) with:

rails server

If you visit localhost:3000 in your browser you should see the splash page.

The Model View Controller Way

Models — these are your "things", and when stored in a database they are tables with columns e.g. a User table/model can have first_name, last_name, email, and other columns/attributes. In a strictly Ruby context, these are objects with attributes.

Views — these are your markup docs (what is loaded in the browser) e.g. HTML. Rails code is often embedded directly through the use of ERb syntax. This can be very icky, abstracted, and frustrating, but is necessary with certain applications.

Controllers - these act as a kind of bridge between views and models. A web request comes in and is routed to a specific controller action which may execute code and/or load variables (Model stuff happens here), a View is then processed (variables expanded, etc.) and sent back to the browser.

An example, say, when you click to see a user's profile:

  • the web request is routed to the Show action of the User controller
  • the Show action loads the user from the database into a variable @user = User.find_in_database (pseudo-code)
  • the show.html.erb view is processed (<h1>@user.name</h1> becomes <h1>Mike</h1> etc.) and sent back to the browser

There are two important pieces missing here...

Firstly, how does rails know how to route a request in the first place?

The config/routes.rb instructs rails how to write requests. Let's say we want a page that shows all users...

We might code this route:

get '/users' => 'users#index'

get is the type of request, /users is www.mysite.com/users and users is the User controller, and index is the action.

Rather than specifying each route for users i.e. we can do this:

resources :users

This sets up all conventional routes.

You will often see the latter, but rarely the former. This is because Rails provides its own syntax for creating multiple routes, rather than having to enumerate each request. So what are the types of requests?

Well, one of the problems that Rails attempts to solve is that of connecting browser actions to database actions... We want to fill out our profile, submit a form, etc...

Most browsers are designed to make only GET and POST requests, but Rails also supports PATCH and DELETE requests. HTML Code can be made to fake to "send" the last two types.

This brings us to our second important missing piece, the database.

As mentioned, Rails coordinates browser actions with database actions e.g. a get request is made and this causes a controller action to do a database action. Rails has some standard actions in controllers which are sometimes expected to perform certain database operations. But, violating these conventions will not cause a syntax error—you'll merely confuse other developers. When you "scaffold" thoroughly, Rails honors these conventions rigidly.

The standard ones (which you will find in the controller) for our user example are:

  • index — asks for all user records; a get request
  • show — asks for one user's record; a get request
  • newget request for form to create new user
  • editget request for form to edit user
  • create — add new user to db; a post request
  • update — update user's record; a patch request
  • destroy - delete user's record; a delete request

Again, these are conventions; nothing stops you from creating bowel_movement action on Gastro controller that drops the entire database.

(In case you were wondering how to determine where the website takes you when you first visit a site.)

This directs all root (/) traffic to the index action in the users controller:

root 'users#index'

More on Databases

At this time Rails uses sqlite as it's default database. As implied, this is a "lightweight" database, and not suitable for large applications.

Many developers prefer to use a postgresql database, and this is the default database used by Heroku for Rails deployments (more on this, later).

If you want to use postgresql locally you will need to install it from brew:

brew install postgresql

Many people set it up to always start upon login:

brew services start postgresql

The other option is to start it directly:

postgres -D /usr/local/var/postgres/

If you have some customized privileges, you may experience issues. This should be a painless process, and the second route (logged in as the appropriate user) may be best if you are experiencing permissions problems.

Adding Postgresql to Rails

If you are just creating your app you can add the -d option and specify postgresql:

rails new my_app -d postgresql

If you already have created your app you will need to add the pg gem to your Gemfile and comment out sqlite3:

#gem 'sqlite3'
gem 'pg'

You will now need to run:

bundle install

You will also need to update config/database.yml. Unfortunately, this not a well tread area for me and I can only point the reader to this google query: "rails changing from sqlite3 to postgresql"; and, say that in the aforementioned file the adaptor may need to be changed to postgresql for each environment, but, especially development and test and the user may need to create databases manually in the command-line (which is not as scary as it seems). Just save yourself the headache and start your app with postgresql.

Back to the big picture

Let's run one command which will more or less build everything we've been talking about:

rails generate scaffold User

If you examine the output you'll see that Rails:

  • created a User model in app/models/user.rbapp/models/ is where your store models
  • created all the routes for our User resource (resource here means everything related to User e.g. views, controller, etc.) in config/routes.rb — again this is where all routes are defined
  • created a User controller and all conventional actions in app/controllers/users_controller.rbapp/controllers/ is where you store controllers
  • created views for the user in app/views/user/ - app/views/ is where you will store most of the pages that are to be sent to the browser

In addition to the numerous other front-end concerns that are installed, you may have also noticed a folder called test/

About Testing

Developers use tests for many reasons:

  • Document code functionality
  • Refactor safely
  • Ensure that code works

Developers test controllers, models, views; and, developers create tests that test all of these in the same test (integration testing). People will argue about how much testing you need, and some will argue that you don't need testing at all.

minitest and rspec are two dominant testing frameworks. Currently, Rails comes with minitest, and rspec must be installed.

Testing goes something like this:

  1. Create a test
  2. Run the test rake test (minitest) see which tests fail/pass

We are more or less on our way

There is one last detail:

Create the database:

rails db:setup

Migrate the database:

rails db:migrate

This creates the database, and runs any outstanding migrations. Migrations are files that make changes to the database. Let's say we want to add posts for our users. If we we want to store these in the database we will need to run a migration.

At this point you may want to stop and restart the server.

Now, go to http://localhost:3000/users and you should be able to see a rudimentary Users page.

The Last Mile

Here are some additional important topics.

Gems

You can add additional functionality to your app without reinventing the wheel.

Here are some noteworthy gems:

  • devise - sophisticated user authentication solution
  • pundit - user authorization
  • twitter-bootstrap-rails - Bootstrap for your rails application
  • pry-rails - debugging console

Most gems can be installed by simply adding the gem to your Gemfile

gem 'my_gem'

And, running

bundle install

Sometimes, gems need additional configuration and setup; see the respective gem's documentation (this is often on github).

Debugging

The gem pry is used to debug Ruby scripts.

You require pry into a script:

require 'pry'

And, this allows you to place:

binding.pry

anywhere in your script, and it will stop the program here and provide you with a console for inspecting your environment e.g. variable values, run functions, etc.

You can use the same tool in Rails with the pry-rails gem.

Rails Console

The rails console can be started with:

rails console

The rails console allows you to interact with your database, among other things. If you want to see what records are in the database, this is the tool.

Heroku Deployment

Heroku is a great tool for deploying Rails apps.

(You'll want to make sure this includes command line client.)

If you haven't already set up a git repository, go ahead and do that.

Now you can create a heroku app with:

heroku create my_app

And, push it to heroku with:

git push heroku master

Now your website would be hosted at https://my_app.herokuapp.com.

Final Words

Keep in mind that although we ran the rails scaffold User command, you will not find yourself using this command much. One reason is that this command adds a bunch of functionality that you may not use. It is more likely that you will find yourself running the commands "in between" this and editing code directly. One such command is rails generate—with it you can generate models, views, controllers, tests, or all of these at the same time.

This tutorial has undoubtedly glossed over, ommitted, and possibly mischaracterized parts of Ruby on Rails. But, hopefully it has given you a good starting point.

If the reader is interested in learning more about Rails, and getting more in depth I would suggest the following:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment