Article
Rails For Beginners: All You Need To Know!
The ActionPack Module
ActionPack is the name of the library that contains the view and controller parts of the MVC architecture. Unlike the ActiveRecord module, these modules are a little more intuitively named: ActionController and ActionView.
Exploring application logic and presentation logic on the command line doesn't make a whole lot of sense; views and controllers are designed to interact with a web browser, after all! Instead, I'll just give you a brief overview of the ActionPack components, and we'll cover the hands-on stuff in Chapter 5.
ActionController (the Controller)
The controller handles the application logic of your program, acting as glue between the application's data, the presentation layer, and the web browser. In this role, a controller performs a number of tasks, including:
- deciding how to handle a particular request (for example, whether to render a full page or just one part of it)
- retrieving data from the model to be passed to the view
- gathering information from a browser request, and using it to create or update data in the model
When we introduced the MVC diagram in Figure 2 earlier in this chapter, it might not have occurred to you that a Rails application can consist of a number of different controllers. Well, it can! Each controller is responsible for a specific part of the application.
For our Shovell application, we'll create:
- one controller for displaying story links, which we'll name StoriesController
- another controller for handling user authentication, called SessionsController
- a controller to display user pages, named UsersController
- and finally a fourth controller to handle story voting, called VotesController
All controllers will inherit from the ActionController::Base class, but they'll have different functionality, implemented as instance methods. (There will actually be an intermediate class between this class and the ActionController::Base class; we'll cover the creation of the StoriesController class in more detail in Chapter 5. However, this doesn't change the fact that ActionController::Base is the base class from which every controller inherits.)
Here's a sample class definition for the StoriesController class:
class StoriesController < ActionController::Base
def index
end
def show
end
end
This simple class definition sets up our StoriesController with two empty methods: the index method, and the show method. We'll expand upon both of these methods in later chapters.
Each controller resides in its own Ruby file (with a .rb extension), which lives within the app/controllers directory. The StoriesController class that we just defined, for example, would inhabit the file app/controllers/stories_controller.rb.
Naming Classes and Files
You'll have noticed by now that the names of classes and files follow different conventions:
- Class names are written in CamelCase (each word beginning with a capital letter, with no spaces between words). There are actually two variations of CamelCase: one with an uppercase first letter (also known as PascalCase), and one with a lowercase first letter. The Ruby convention for class names requires an uppercase first letter.
- Filenames are written in lowercase, with underscores separating each word.
This is an important detail! If this convention is not followed, Rails will have a hard time locating your files. Luckily, you won't need to name your files manually very often, if ever, as you'll see when we look at generated code in Chapter 5.
ActionView (the View)
As we discussed earlier, one of the principles of MVC is that a view should contain presentation logic only. This principle holds that the code in a view should only perform actions that relate to displaying pages in the application -- none of the code in a view should perform any complicated application logic, nor should it store or retrieve any data from the database. In Rails, everything that is sent to the web browser is handled by a view.
Predictably, views are stored in the app/views folder of our application.
A view need not actually contain any Ruby code at all -- it may be the case that one of your views is a simple HTML file. However, it's more likely that your views will contain a combination of HTML and Ruby code, making the page more dynamic. The Ruby code is embedded in HTML using embedded Ruby (ERb) syntax.
ERb is similar to PHP or JSP in that it allows server-side code to be scattered throughout an HTML file by wrapping that code in special tags. For example, in PHP you may write code like this:
<strong><?php echo 'Hello World from PHP!' ?></strong>
The equivalent code in ERb would be the following:
<strong><%= 'Hello World from Ruby!' %></strong>
There are two forms of the ERb tag pair: one that includes the equal sign, and one that doesn't:
<%= ... %>
This tag pair is for regular output. The output of a Ruby expression between these tags will be displayed in the browser.
<% ... %>
This tag pair is for code that is not intended to be displayed, such as calculations, loops, or variable assignments.
An example of each ERb tag is shown below:
<%= 'This line is displayed in the browser' %>
<% 'This line executes silently, without displaying any output' %>
You can place any Ruby code -- be it simple or complex -- between these tags.
Creating an instance of a view is a little different to that of a model or a controller. While ActionView::Base (the parent class for all views) is one of the base classes for views in Rails, the instantiation of a view is handled completely by the ActionView module. The only file a Rails developer needs to modify is the template, which is the file that contains the presentation code for the view. As you might have guessed, these templates are stored in the app/views folder.
As with everything else Rails, a strict convention applies to the naming and storage of template files:
- A template has a one-to-one mapping to the action (method) of a controller. The name of the template file matches the name of the action to which it maps.
- The folder that stores the template is named after the controller.
- The extension of the template file is twofold and varies depending on the template's type and the actual language in which a template is written. By default there are three types of extensions in Rails:
html.erbThis is the extension for standard HTML templates that are sprinkled with ERb tags.xml.builderThis extension is used for templates that output XML (for example, to generate RSS feeds for your application).js.rjsThis extension is used for templates that return JavaScript instructions. This type of template might be used, for example, to modify an existing page (via Ajax) to update the contents of a<div>tag.
This convention may sound complicated, but it's actually quite intuitive. For example, consider the StoriesController class defined earlier. Invoking the show method for this controller would, by default, attempt to display the ActionView template that lived in the app/views/stories directory. Assuming the page was a standard HTML page (containing some ERb code), the name of this template would be show.html.erb.
Rails also comes with special templates such as layouts and partials. Layouts are templates that control the global layout of an application, such as structures that remain unchanged between pages (the primary navigation menu, for instance). Partials are special subtemplates (the result of a template being split into separate files, such as a secondary navigation menu or a form) that can be used multiple times within the application. We'll cover both layouts and partials in Chapter 7.
Communication between controllers and views occurs via instance variables that are populated from within the controller's action. Let's expand upon our sample StoriesController class to illustrate this point (there's no need to type any of this out just yet):
class StoriesController < ActionController::Base
def index
@variable = 'Value being passed to a view'
end
end
As you can see, the instance variable @variable is being assigned a string value within the controller's action. Through the magic of ActionView, this variable can now be referenced directly from the corresponding view, as shown in the code below:
<p>The instance variable @variable contains: <%= @variable %></p>
This approach allows more complex computations to be performed outside the view -- remember, it should only contain presentational logic -- and allow the view to display just the end result of the computation.
Rails also provides access to special containers, such as the params and session hashes. These contain such information as the current page request and the user's session. We'll make use of these hashes in the chapters that follow.