Loccasions: Installing Rails Part 2

Glenn Goodrich
Ruby Editor
This entry is part 3 of 15 in the series Loccasions

Loccasions

Rails Gem Dependencies, Continued

We left off with the TZInfo gem last time, and we’ll start with ERubis in this article.

Erubis
Erubis is an implementation of eRuby, which is the Ruby expressions between the <% %> in Ruby views.

ActionPack
ActionPack is kind of a big deal. The rubydoc for ActionPack states that it “provides the view and controller layers in the MVC paradigm”. You could argue that it is two-thirds of Rails. It includes ActionDispatch (routing and HTTP goodness, like caching, sessions, and cookies), ActionController (provides the base class for Rails controllers). ActionView (handles the views and rendering of formats like HTML or ATOM feeds).

If you want to really learn about Rails, doing a deep dive on ActionPack will take you far.

Arel
Arel is what gives ActiveRecord (effective Rails 3) its cool syntax. It is a “SQL AST manager,” where “AST” meaning “Abstract Syntax Tree.” An AST is one of those super-nerd concepts that separates the Geniuses from the rest. Explaining an AST is way outside the scope of this article (not to mention the scope of my brain).

ActiveRecord
ActiveRecord is the default object-relational mapper (ORM) used by Rails. Basically, it maps your model to the database structure. You can use other ORMs such as DataMapper if you prefer.

ActiveResource
ActiveResource is the gem that gives Rails its nice, RESTful interface, which (in this author’s opinion) is possibly the best feature of Rails. Understanding REST is key to being a good web developer. A great place to start learning REST is in the O’Reilly book, RESTful Web Services.

MIME Types
The MIME Types gem is used by Rails to identify the MIME type of a request, such as mapping text/html to HTML, etc.

Polyglot
Polyglot registers file extensions to be used with Ruby require statements. So, if you wanted to load files with an ‘.funk’ extension, the ‘.funk’ extenstion can be registered with Polyglot. Then, require 'wegotthe' would find a file named “wegotthe.funk”.

Treetop
Treetop is another gem that handles a guru-level concept, allowing the developer to create syntax and parse “expression grammars” easily. Treetop is used, in its most basic way, to add syntax to a language (I would explain more, but this post would explode).

Mail and ActionMailer

These gems focus on (you guessed it) sending mail from Rails. Mail handles the generation, sending, parsing of e-mail, while ActionMailer creates the “mailers” (think: controllers for e-mail) and views for mail templates.

Thor
Thor helps build command line tools and utilities. It is often seen as a competitor to Rake, the default Ruby make tool, and has quite a committed following. Thor is one of those gems you would do well to research and incorporate into your Ruby arsenal (by Odin’s Beard!).

Rack SSL
The Rack SSL gem provides a middleware to support Transport Level Security (TLS), the most common is Secure Socket Layer (SSL). Here is a good article on it’s use.

RDoc
RDoc simplifies the creation of HTML-based documentation and it is used to document Rails itself.

Railties
Railties, starting at 3.0, has been included in core Rails. Railties are (arguably) THE way to extend Rails, and many of the major components, like ActionMailer, ActionController, and ActionView are Railties. Understanding how Railties work is another key task for the budding Rails developer. Here is a good article to whet your appetite.

Bundler
Bundler is the way Rails manages its gem dependencies. Bundler uses the Gemfile in the root of the Rails app to make sure all the necessary gems are available and any conflicts are identified. Spend some time on the Bundler site to see how many options for loading gems are available.

Rails
In my previous article, I mentioned that the Rails gem only includes the Rails executable, which is slightly misleading. If you inspect the source on Github, you can see that it includes many of the gems discussed in these two articles. You may want to start your code browsing here.

We’ve now covered gem dependencies in Rails 3.1. Even though Rails has a reputation of being a simple web framework, there is a lot of work that goes into building that simplicity.

Rails Application Generation

It’s finally time to generate our Rails app. As you may expect, I’ll go through all of the options available before creating the app, so strap in for another deep dive. Let’s start by looking again at the Rails executable, a particular part of the Rails gem. [Aside: I like to use the open_gem gem to quickly open a particular gem in my editor (vim). Once open_gem is installed, you just type "gem open " and the command line and your editor opens in the gem's directory.] The rails gem directory only has a bin subdirectory with the rails executable. The source for this executable is alarmingly terse:

 #!/usr/bin/env ruby 
if File.exists?(File.join(File.expand_path('../..', __FILE__), '.git')) 
  railties_path = File.expand_path('../../railties/lib', __FILE__) 
  $:.unshift(railties_path) 
end 
require "rails/cli" 

In a nutshell, a check is run to see if the current environment is running from local source (meaning, a Git repository) and the path to the railties gem is shifted as a result. After that, the cli file is required. This file lives in the railties gem, and basically checks to see if we are inside of a Rails application directory or not. If we are in a Rails applcation, then the rails executable acts like a script, otherwise we are generating a new application or plugin.

Right now, we want to focus on creating an application, which is handled by rails/commands/application.rb in the railties gem.

 
require 'rails/version' 
if ['--version', '-v'].include?(ARGV.first) 
  puts "Rails #{Rails::VERSION::STRING}" 
  exit(0) 
end 
if ARGV.first != "new" 
  ARGV[0] = "--help" 
else 
  ARGV.shift 
end 

require 'rubygems' 
if ARGV.include?("--dev") require 'rails/generators' 

require 'rails/generators/rails/app/app_generator' 
module Rails 
  module Generators 
    class AppGenerator 
    # We want to exit on failure to be kind to other libraries 
    # This is only when accessing via CLI 
      def self.exit_on_failure? 
        true 
      end 
    end 
  end 
end 

Rails::Generators::AppGenerator.start 

After a version check, the script makes sure that “new” is the first argument, otherwise it forces the “–help” argument. This check stops the problem where you may accidentally mistype an argument that results in a new Rails app in that mistyped directory name (I used to do this ALL the time!).

If all is well, we pull in the AppGenerator and start it up. The AppGenerator code is found, also in the railties gem, in rails/generators/rails/app/app_generator.rb. The full source of this file is a bit too large to post, but you should open it and take a look. I was pleasantly surprised how simple the code is to follow and saw immediately how I could modify Rails app generation. That same directory has a templates directory, which (as you might have guessed) is the base directory structure of a new Rails application. The app_generator.rb file has a couple of classes defined within: Generators::AppGenerator and AppBuilder.

There are methods in the AppBuilder class like copy_file and empty_directory_with_gitkeep that beautifully indicate how a new application is created from the template. If you want to generate any kind of directory structure in your own projects, studying the AppBuilder class shows a fantastic and maintainable approach.

The AppGenerator class which inherits from AppBase. AppBase (find it in rails/generators/app_base.rb in the railties gem) defines the vast majority of the available options for generating an application, which will go over shortly (meaning, next post). AppGenerator contains an AppBuilder class, which handles the actually building of the structure of the application. You can override the builder class as part of the options of the “rails new” command.

In the next post, we’ll go over each of the options for creating a new rails application and why you might want to use these options. My goal is to generate our Rails application so we have something tangible. I hope you are enjoying this deeper look at getting started with Rails. If there are bits of a Rails introduction you’d like to see or think I am missing, leave a comment below.

Loccasions

<< Rails Intro, Deep Dive: Installing Rails, Part OneRails Intro, Deep Dive: App Generation >>

Win an Annual Membership to Learnable,

SitePoint's Learning Platform

  • iWantToKeepAnon

    *ActiveRecord*

    *ActionRecord* is the default object-relational mapper ….

    … typo?

    • http://www.ruprict.net/ Glenn Goodrich

      Whoops!

      Thanks for catching that

  • http://twitter.com/thatandyrose andy

    hey glenn, just want to say how useful this resource is. learning RoR now and this has been immensely useful!

    Thank you!

    I’m blogging my progress here: http://commitandrun.tumblr.com/tagged/learningrubyonrails

    • http://www.ruprict.net/ Glenn Goodrich

      Excellent stuff, Andy! Hope you’re catching the Ruby bug….:)