I am interested in learning Ruby and its Rails website framework for two reasons:
1) To build quick websites.
2) Ruby seems like a useful tool.
This code article will simply be my notes from the Dreamforce 2013 developer session named "Hands-on Ruby on Rails - Build your First App". Here is its recording on YouTube that I'll be using, here are the slides on SlideShare, and here is the code artifacts on GitHub.
- Introduction to Ruby, Rails, and Heroku
- Getting Started
- Building a Blogging App
- Deploying to Heroku
Intro to Ruby and Rails
- Ruby was created in 1995 by a Japanese guy known as Matz.
- Ruby designed to be a cross-platform, simple scripting language.
- Rails is a web app framework which uses MVC, which helps organize code.
- Rails is designed to be simple by using fewer config files and good architectural patterns.
- Rails uses routes, which means it is easy to make a RESTful web app.
Rails has a mantra - convention over configuration. One of those is directory structures:
Getting Started with Heroku
Heroku is nice and you should use it.
Install Rails Tools
- Install Heroku Toolbelt (CLI, Foreman, Git) - (I previously had installed)
- Install RVM, RubyGems, and also Homebrew if on Mac
- Install Ruby 1.9.2 (I previously had installed)
- Install Rails
- Install PostgreSQL
- Heroku Quickstart
The speaker assumes the audience already had Rails installed. I do not, however, so I'll install that now. I'll be using the RailsApps install guide.
This guide recommends using rvm to manage Ruby and Rails versions. Why do we want rvm? It manages your app's libraries and frameworks which simplifies upgrading versions. First, rvm downloads and installs Ruby versions and gem versions into its repository which is in the
~/.rvm directory. Then, rvm sets all references to these, which is how your app finds them, such as the PATH.
- Install rvm
$ \curl -L https://get.rvm.io | bash -s stable --ruby
Quick rvm Tutorial
To specify and maintain the version of Ruby we want to use, specify the version like this. (Note: To see all Ruby versions that rvm supports, execute
rvm list known.)
$ rvm 1.9.2-head
rvm enables you to create a 'gemset' to manage versions of dependencies, such as libraries or frameworks. Before upgrading to a new version of Rails, the guide recommends using rvm to create a
gemset container in which to test it.
$ rvm gemset create rails222 rails126
With a gemset for the new Rails version, you can switch to that container and install Rails inside it.
$ rvm 1.9.2-head@rails222 $ gem install rails -v 2.2.2 $ rvm 1.9.2-head@rails126 $ gem install rails -v 1.2.6
Now that a gemset is defined for each version of the Rails gem, we can switch to each version of Rails like this.
$ rvm 1.9.2-head@rails222 $ rails --version # Rails 2.2.2 $ rvm 1.9.2-head@rails126 $ rails --version # Rails 1.2.6
While we won't be using these advanced features of rvm, knowing the extent of this tool is still useful. We will be using just one feature of rvm, which is to install the latest Ruby version. If you didn't already do it, install the latest Ruby like this.
Install the Latest Ruby
$ rvm 1.9.2-head
Now that we have the latest Ruby, we can continue following the Rails install guide here at the 'Install Rails 3.2.11' section.
The rvm package includes RubyGems, which is a package manager for Ruby. This tool makes it easy to use frameworks and libraries that exist in the Ruby ecosystem by centrally hosting various versions of registered packages or arbitrary code. We will use RubyGems to install the Rails package.
$ gem install rails $ rails -v
I am using Ubuntu 12.04. Rails will attempt to use SQLite as a default database solution. Bundler will install the
sqlite3 Ruby package, which is the Ruby interface code to the SQLite database software. If the SQLite software doesn't exist on the system, this Ruby package can't interface with it, and will cause an error. I haven't installed any database software yet, so generating a default Rails app will fail. To solve this, we need to install the
sqllite3 database software using apt-get.
$ sudo apt-get install sqlite3 libsqlite3-dev
Rails is not only a web app framework, but it is also a code generator. Rails can generate a complex application that has many components. Because these components work together out of the box, your job as a web app dev is to customize the app, rather than spending lots of time gathering app components, connecting them together, and testing them.
So, let's tell Rails to generate a new app for us. It only requires us to name the app. Let's name it 'blog'.
$ rails new blog
This creates the directory structure for a web app and fills it with default HTML, CSS, and JS files. It also sets up the HTTP server and Ruby classes that handle HTTP requests. Most importantly, this generates our app's bundle file.
There are many libraries and third-party apps, such as an HTTP server, that compose our app. These dependencies are all collected into a single location, called a 'bundle' file. A tool called 'Bundler' reads this file to download and install these dependencies into our app for it to use.
One of these dependencies is a database solution.
Setting up Databases
Rails uses SQLite as its default database. This is a nice database because it's fast, which makes development more fun. However, because the production environment might require a heavier database, we might want to use two different databases - one for development and one for production. The PostgreSQL database has some really cool features, and Heroku likes this database, so I want to use it in production. Rails supports using multiple databases like this, so let's take a look.
Bundler installs our database software. We can ask Bundler to install SQLite if the environment is called 'development', and install PostgreSQL if it is called 'production'. Let's set up Bundler to do this.
Define different development and production databases
- Open the
gemfilefile, which is located in the rails app's root directory.
- Find the
Replace this line with the following
group :production do gem "pg" end
group :test do gem "sqlite3" end
- Open the
Now, when this app is deployed to production and installed, Bundler will run, see that it's on production, and install PostgreSQL instead of SQLite to use. We can run Bundler on our app right now, in test mode, and I believe it will still download PostgreSQL, but not use it.
If we try to install this additional dependency now, it will fail because we haven't installed the PostgreSQL software to which this gem will attach. So let's install PostgreSQL.
Install PostgreSQL and header files for libraries
$ sudo apt-get install postgresql-9.1 $ sudo apt-get install libpq-dev
We can test this by running Bundler on our app again.
Install app dependencies with Bundler
Navigate to the Rails app's root directory.
$ bundle install
Set up Data Model & Scaffolding
Our blog will be simple - its posts will have only a 'title' and a 'body'.
Adding a new database object to an application traditionally isn't as simple as clicking an 'Add' button. There are a few places to make this addition, namely in the database, in the persistence layer definitions, and Ruby classes to match the new object. These changes can be predictable for most use cases, so Rails can generate this code for us. In Rails, this stack of code for using and persisting an object in this manner is called a 'scaffold'. So, let's have Rails make this scaffold for us.
Make a new persistable object in Rails
- Navigate to your app's root directory
Execute the following command to define and implement a new model named 'Post'
$ rails generate scaffold Post title:string body:text
$ sudo apt-get install nodejs
When the scaffold script is running, you can see it create some Ruby files, some Ruby HTML templates, and some CSS files. Let's feel lucky we didn't have to write that ourselves.
Customize Model's View Page
In customizing our app, we will spend majority of our time in a few places.
When a user navigates to our app using a web browser, they will be requesting files from our
views directory. Each view will have dynamic data behind it, so a developer will be modifying the respective controller, which are in the
That's all we need to know about this for now.
Changing the Landing Page
The default landing page for out web app is a static page, specifically the
One way we can customize the landing page is to define a dynamic route matcher. When a user enters a URL, something like
posts/12345 bit is called the route.
Your app may want to listen for these routes and respond when a pattern is matched. You can define such patterns in the
config/routes.rb file. Let's add a route matcher for request for our app's root.
Add a route match for root
- Open the
Add this line near the top
root :to => "posts#index"
Save the file
- Open the
Now, Rails will only use our routes mapping for a root request only if the
public/index.html file doesn't exist. So, to activate our root mapping, we have to hide this file. Let's just change its name.
Hide the default root file
Rename the root file by executing this from the root directory
$ mv public/index.html public/index.html.bak
When we start our app and navigate to the root page, we should see the index page for our posts.
Testing Our App Locally
Most of initializing and starting our app locally involves database preparation. We used Rails'
scaffold command to add a Post object to our app. This command also added entries to our database management scripts, which is convenient. All we're left to do is run those scripts. Then, we can start our app server and test it with a web browser.
Create the database
$ rake db:create
Run database migrations
$ rake db:migrate
Start the app
$ rails server
When you navigate to
0.0.0.0:3000 in your web browser, you should see a boring page that says "Listing posts" and has a "New Post" link.
Congrats! We have a working app!
After following the Rails walkthrough as organized by Chris Kemp, it seems like a pretty simple platform on which to create web apps. Do I dare say that it seems to be as simple as making Force.com apps?
Yes, figuring out what you need to start working on a Rails app and setting up your environment is a bit of work, but once prepared, customizing your app seems to be really straight-forward.
I'm curious how web apps manage user authentication and permissions, so I'll be looking into that next. It looks like Rails has good support for two authentication frameworks/libraries, called Devise and OmniAuth. I have no idea how these work, but the RailsApps group seems to have a good tutorial on creating a Rails app which uses Devise and Mongoid, so I'll be looking at this next.
Thanks for reading!