Zend certified PHP/Magento developer

RubySource: Rails Development 101: Installing Rails, Part II

Rails Gem Dependencies, Continued

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

Erubis is an implementation of eRuby, which is the Ruby expressions between the % % in Ruby views. 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 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 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 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.

The MIME Types gem is used by Rails to identify the MIME type of a request, such as mapping codetext/html/code to HTML, etc. 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, coderequire ‘wegotthe’/code would find a file named “wegotthe.funk”.

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). The Mail and ActionMailer 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 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!).

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 simplifies the creation of HTML-based documentation and it is used to document Rails itself. 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 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. 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.