Ruby on Rails is a framework that has revolutionized the way we build modern web applications with speed, structure, and elegance. Today, as part of our Miner’s Guide to Code Crafting series, we will explore it further.
Web development is a crucial area in modern technology, especially with the growing demand for applications that can be accessed from anywhere. Building applications requires attention to various layers, such as the user interface, data storage, and application logic. Each of these components plays a specific role in ensuring everything works seamlessly and effectively.
In this context, Ruby on Rails, or simply Rails, is a web development framework written in Ruby and designed to establish a standard for development teams. Created to streamline and simplify web application development, Rails follows the principle of "Convention over Configuration." This means it provides predefined standards for structuring projects, reducing the number of decisions developers need to make.
MVC
Rails adopts the MVC (Model-View-Controller) pattern to organize code according to specific responsibilities. Each part of MVC corresponds to a layer of the application, each with a distinct role:
Model: Responsible for interacting with the database and managing business logic.
View: Handles the presentation of information to the user.
Controller: Connects models to views, processing requests, and determining what information will be displayed.
Let’s start by looking at how controllers and views work together to handle requests and deliver information in a Rails app.
First things first
When an HTTP request reaches our application, the first point of contact is the routes file, which is responsible for mapping the received URL to a specific controller and action. In Rails, this routes file is located at config/routes.rb
and comes pre-configured, allowing developers to adapt it according to the application’s needs. Routes in Rails are defined as follows:
Rails.application.routes.draw do
get ‘/welcome’, to: ‘home#welcome’
resources :users
end
In the example above, the first line maps the /welcome
URL to the welcome
action in the home
controller, which handles the request and returns the response to the client.
Additionally, the use of resources
simplifies the creation of RESTful routes for a resource called users
. This convention automatically generates all the necessary routes for standard CRUD (Create, Read, Update, Delete) operations, such as creating, editing, updating, and deleting users.
For instance, the command resources :users
generates routes like:
GET /users
to list users;POST /users
to create a new user;GET /users/:id
to display details of a specific user;PATCH/PUT /users/:id
to update a user;DELETE /users/:id
to delete a user.
These conventions make development faster and more organized, ensuring consistent code structure. The interaction between the application’s routes and controllers is fundamental: when a route is identified, Rails forwards the request to the appropriate controller, which then processes the data and determines the response to send back to the client.
Controllers
Controllers are an essential part of the MVC pattern and are responsible for handling incoming requests and deciding what will be returned to the client. They act as intermediaries between routes, models, and views, connecting the application’s logic with the data needed to generate responses.
Rails provides a straightforward way to create controllers. For example, the following command can be used to generate a controller:
rails generate controller Users index
This command automatically creates a file named UsersController
inside the app/controllers
directory. Additionally, Rails generates the necessary structure for a view corresponding to the index
action. Controllers in Rails follow a convention where each action (or method) handles a specific request. A typical example of a controller would be:
class UsersController < ApplicationController
def index
@users = User.all
end
end
In the example above, the index
action is responsible for retrieving all user records from the database using the User.all
method and making them available to the corresponding view. The instance variable @users
will be used in the view to display the data appropriately.
An important point is that all controllers in Rails inherit from ApplicationController
, which provides shared functionality across all controllers in the application. This includes, for example, the ability to apply filters before or after specific actions, such as user authentication.
Controllers also play a vital role in organizing the code, allowing request-handling responsibilities to be separated into different classes. This structure makes the development and maintenance of the application more organized.
Views
After processing, the controller must decide what will be returned to the client. Response options include HTML files, JSON, or even redirects. This is where the V in the MVC pattern comes into play: the views of the application.
Views are responsible for rendering information to the user in a visual format. In Rails, they are directly associated with a controller, which simplifies the transfer of processed data from actions to the presentation layer. This association also establishes a standardized structure, making development more organized and coherent.
The view files in a Rails application are located in the app/views
directory. Within this folder, views are organized into subdirectories corresponding to each resource and the actions of the controllers. For example, for the users
resource and the index
action, the corresponding view file will be app/views/users/index.html.erb
.
A typical example of an index.html.erb
file would be:
<h1>Users</h1>
<ul>
<% @users.each do |user| %>
<li><%= user.name %></li>
<% end %>
</ul>
In this example, the view file uses the .erb
extension (Embedded Ruby), which is the default templating engine in Rails. ERB allows the combination of Ruby code with HTML within the same file. Ruby is embedded using
is used to display each user’s name in the generated list. tags for executing code or
for displaying values. In the example above,
is used to iterate over a collection of users, and
Views generate the HTML sent to the client’s browser, where it is rendered. For instance, in the code above, the browser displays a title and a dynamically generated user list based on the data provided by the controller.
Although ERB is the standard for Rails views, other templating options like HAML and SLIM offer alternative syntaxes for writing HTML and Ruby.
Another important aspect of Rails views is the use of instance variables, like @users
in the previous example. These variables are defined in controller actions and are automatically made available to the corresponding view. This seamless integration between controllers and views is one of Rails’ strengths, as it reduces the complexity of sharing data across layers.
Other technologies
In addition to rendering HTML in the client’s browser, web pages often utilize other technologies like CSS and JavaScript to enhance the appearance and behavior of the interface. To manage these resources, Rails offers the Asset Pipeline, an optimized solution for organizing and serving static files.
The Asset Pipeline in Rails is a library designed to organize, optimize, and serve static files such as JavaScript, CSS, and images. It improves performance and maintainability by enabling:
- Organization: Centralizes and standardizes assets in the
app/assets
folder. - Caching and Compression: Performs minification, concatenation, and fingerprint generation for better performance.
- Preprocessing: Supports languages like Sass and CoffeeScript.
Importmap-rails is a modern alternative that simplifies JavaScript management in Rails, eliminating the need for tools like Node.js. It leverages native browser support for ES Modules, loading modules directly via “, without requiring bundling or transpiling.
Benefits of importmap-rails:
- No Node.js or build tools: Dependencies are managed via
bin/importmap
and hosted on CDNs like jsDelivr. - Instant updates: During development, no build step is required, so changes are immediate.
- Integration with Propshaft: In production, Propshaft optimizes file serving with caching and fingerprinting.
This approach is ideal for applications that use modern JavaScript and do not require complex tools like Babel or Webpack.
Starting with Rails 8, the default asset pipeline is Propshaft. Propshaft is a modern asset pipeline library for Rails, designed for a context where practices like bundling and minification are no longer essential. With the rise of dedicated Node.js bundlers and increased bandwidth, it has become possible to greatly simplify the asset pipeline, replacing more complex tools like Sprockets.
Propshaft offers important features such as configurable load paths, asset digesting for improved production caching, and serving assets directly in the development environment without the need for precompilation.
Conclusion
In summary, Rails is a framework that exemplifies the application of the MVC (Model-View-Controller) pattern, clearly separating the responsibilities of each layer to simplify the development and maintenance of web applications. Controllers process requests and connect the data provided by models to views, which are responsible for dynamically and interactively presenting information to users. The principle of Convention over Configuration promotes an organized and standardized way of designing applications, making development and maintenance more straightforward. Additionally, tools like the Asset Pipeline and importmap-rails enhance the ecosystem, streamlining asset management in true Rails way.
Previously: Full Steam Ahead: Getting Started with Ruby on Rails
This post is part of our ‘The Miners’ Guide to Code Crafting’ series, designed to help aspiring developers learn and grow. Stay tuned for more and continue your coding journey with us!! Check out the full summary here!
We want to work with you. Check out our "What We Do" section!