Skip to Main Content

Ruby on Rails

Ruby is an open-source programming language originally released in 1995, known widely for its simplicity and expressiveness. It was designed by Yukihiro “Matz” Matsumoto, with the goal of creating a language “optimized for programmer happiness.”

Ruby on Rails (often shortened to just “Rails”) is an open-source web application framework originally released in 2004. It was designed with a focus on “convention over configuration.” Since its original release, it has undergone multiple transformations, regularly both adopting and informing industry best practices.

As a combined package, the language and framework are an established and trusted toolkit for building high-quality web applications quickly and safely. The expressiveness of Ruby allows business concepts to be represented in a natural way, leading to code that’s easy to understand and maintain. The organization of Rails––and its focus on meaningful abstractions and conventions––takes the guesswork out of structuring and implementing new features.

For these reasons and more that we’ll explore below, Ruby on Rails has served as a backbone of TXI’s web application engineering practice for over a decade.

Ruby on Rails

What is Ruby on Rails?

Ruby was released in late 1995 by Yukihiro “Matz” Matsumoto, a Japanese computer scientist who sought to blend together various aspects of his favorite programming languages in an effort to create a language that felt natural and intuitive to work in while striking a balance between imperative and functional programming styles. One of the core facets of the language is that “everything is an object,” meaning that nearly every piece of information in a Ruby program––“primitive” data types like strings and numbers in addition to the more complex data structures––can have behaviors redefined, or have new behaviors added. This makes Ruby capable of expressing its logic in a way that simply isn’t possible in many other languages.

While its syntax and expressiveness are key selling points of the language, Ruby became widely adopted in large part due to the open-source programming community that sprung up around it. In 2004, “RubyGems” was released, a toolkit and repository for publishing and downloading Ruby libraries known as “gems.” The RubyGems ecosystem was later made part of the language’s core with the release of Ruby 1.9 in 2007, and immediately laid the groundwork for the language’s evolution, simplifying the process of sharing code with other developers.

Chief among the projects responsible for Ruby’s widespread popularity was Ruby on Rails. Rails was released by Danish programmer David Heinemeier Hansson in 2004. It was an open-source project extracted from Basecamp, a project management application created by the web development firm 37Signals. Upon its introduction, Rails brought several key innovations to the web development industry, including seamless database migrations and simple patterns for rendering stored data to web views. It adhered (and still does) to the Model-View-Controller (MVC) pattern, which divides an application’s responsibilities of storing, displaying, and modifying data in a focused and predictable way.

The intersection of intuitiveness and convention offered by the combination of Ruby and Rails makes the language and framework particularly approachable, and means applications built with them are straightforward to maintain.

Since their initial releases, both the language and the framework have undergone several major version updates that have maintained their positions on the leading edge of programming and web development, adopting new technologies and patterns as the software engineering industry has continued to evolve. Rails famously served as the framework on which Twitter was originally built. While some of their celebrity has faded over time, Ruby and Rails have proven themselves to be fast, reliable tools for turning ambition into reality.

Ruby on Rails

What is Ruby on Rails used for?

Ruby on Rails is an effective choice of framework when a project’s chief concerns are delivery timeline and usability. At TXI, we frequently lean on Rails for New Lines of Business, Rapid Prototypes for Product Innovation, and User-Friendly Interfaces for Legacy Systems.

New Lines of Business

Ruby on Rails is probably at its best for building greenfield applications in the early stages of a project’s life cycle, when an idea feels right but the dominant risk is establishing a presence in the market.

Rails’s clear structure and organic syntax make changes easy to perform as assumptions are made and revisited, and as user feedback starts coming in. The maturity of the framework and its surrounding ecosystem of third-party libraries cut down on the overhead of scaffolding a project, allowing us to put the lion’s share of the focus where it should be: quickly delivering an impactful product to our clients and their customers.

Ruby is particularly well-suited for handling user input, with a large number of baked-in features around text parsing and manipulation. This allows Ruby on Rails to support multiple request formats (such as HTTP, XML, and JSON) with minimal development effort and enables straightforward patterns for the creation and updating of database records in response to those requests. These features also contribute to the framework’s implementation of best-practice countermeasures to mitigate the vast majority of common attack vectors for web applications.

Ruby’s large open-source community further accelerates development of web applications by supplying mature solutions for many common web application needs, like authentication and permissions management. These existing tools mean we can spend less time reinventing the wheel, and spend more time solving the unique problems faced by our clients and their customers.

Rapid Prototypes for Product Innovation

The primary strengths of Ruby on Rails are the expressiveness of the language and the ease with which the framework allows for new applications to be created and populated with data and functionality. This makes it an ideal framework for rapid prototyping and building proofs of concept.

The same factors that make Ruby on Rails an excellent choice for implementing novel software-as-a-service (SaaS) platforms make it a great option for innovation work. Here at TXI, we frequently use the framework for scaffolding throwaway projects, getting clients’ ideas off of paper and into a browser. The quick engineering turnaround possible in this stack lets us test designs and validate project-level assumptions with minimal implementation cost.

User-Friendly Interfaces for Legacy Systems

Ruby on Rails has a strong niche for serving as an abstraction layer in front of clumsy legacy systems. The flexibility of the language makes it an excellent choice for crafting Domain-Specific Languages (DSLs) and wrappers for third-party APIs. This positions the framework well for creating robust experiences on top of existing software.

While Ruby as a language is not known for its speed, the vast majority of performance issues that are likely to crop up in a web application are resolvable by implementing appropriate best-practice techniques like caching, query optimization, and database sharding. The performance overhead of any web framework often constitutes just a fraction of the overall request time, and we’ve successfully scaled our clients’ Rails applications to handle thousands of requests per second without issue.

Still, Ruby may not be the right language choice for certain use cases involving machine learning or data science, where quickly crunching large amounts of information is a critical business feature. In these cases, it often makes sense to use Ruby on Rails as a dedicated service layer for providing visibility into a back-end data processing service built using a more performant or specialized technology.

Ruby on Rails

Demonstration

The Model Layer (ActiveRecord)

Let’s imagine we’re a manufacturing company looking to automate the administration of the industrial equipment used in our warehouses. One of the strengths of Ruby on Rails when building an application is its ability to easily align the code implementation with our actual business terminology.

# app/models/warehouse.rb
class Warehouse < ApplicationRecord
    has_many :equipment
end

# app/models/equipment.rb
class Equipment < ApplicationRecord
    belongs_to :warehouse
end

Here, we’ve created two “models” to represent our business case. We have our warehouses, and the equipment installed in those warehouses. The above is already giving us quite a bit of functionality for free.

For instance, with the associations we’ve defined here, we can easily grab all of the equipment installed at a specific warehouse with:

warehouse.equipment

But it’s straightforward to add considerably more powerful interactions here. Let’s take a look at the database configuration for our Equipment model:

# db/migrate/20230101010000_create_equipment.rb
class CreateEquipment < ActiveRecord::Migration[7.0]
    def change
        create_table :equipment do |t|
            t.string :name, null: false
            t.references :warehouse, null: false, foreign_key: true
            t.integer :status, default: 0
        end
    end
end

This migration file creates an “equipment” table in our database with a name field, a reference to a Warehouse record, and a status field. With Rails’s philosophy of convention over configuration, the Equipment model we defined earlier doesn’t need to have any of this information provided to it! Because the table name aligns with our model name, our application can automatically identify the fields we’ve added to the database and understand how to interact with them.

Let’s put that status field to use:

# app/models/equipment.rb
class Equipment < ApplicationRecord
    belongs_to :warehouse
    enum status: [:ordered, :delivered, :installed, :configured, :running]
end

Here, we’ve told the application that our status field should be treated as an enumeration over several different workflow states for our equipment. We might have different criteria for moving between these states, but this one line immediately grants us the ability to filter our Equipment records in multiple ways. Now if we want to pull a list of all the equipment at a warehouse that has been delivered but not installed, we can simply do this:

warehouse.equipment.delivered

This is a very barebones but hopefully illuminating peek into why ActiveRecord, the model layer of Ruby on Rails, is so powerful for quickly implementing web applications.

The Controller Layer (ActionController)

Let’s take this example another step, and see how ActionController, the Controller layer of Rails, fits into our application:

# app/controllers/equipment_controller.rb
class EquipmentController < ApplicationController
    def create
        @equipment = Equipment.new(resource_params)
        if @equipment.save
            redirect_to equipment_index_path, notice: "You successfully added new equipment!"
        else
            render :new
        end
    end

    private

    def resource_params
        params.require(:equipment).permit(:name, :warehouse_id, :status)
    end
end

There’s a bit more going on here, because we’re setting up a lot of new functionality. With the appropriate routes configured for our application, the “create” action we’ve defined here will accept HTTP POST requests to “www.manufacturing.co/equipment”, use the submitted information to construct an Equipment record, and persist it to the database so we can interact with it elsewhere in our code. The resource_params method above is a baked-in security feature of Rails––before any information can be used to create or update a record, it has to be marked as safe / expected by the controller.

This mechanism is useful for ensuring that users can’t update internal fields that shouldn’t be modified; for instance, if we wanted our Equipment “status” to come from an external processing system, we could remove it from the supported params list here to prevent users from updating the status manually through our API.

The View Layer (ActionView)

We have our API in place now, but how might a non-engineer interacting with our application create a piece of Equipment themselves? This is where the View layer, powered by ActionView in a Rails application, comes in:

# app/views/equipment/new.html.erb
<%= form_for @equipment do |form| %>
    <%= form.label :name %>
    <%= form.text_field :name %>
    <%= form.label :warehouse_id %>
    <%= form.collection_select :warehouse_id, Warehouse.all, :id, :name, prompt: true %>
    <%= form.label :status %>
    <%= form.select :status, options_for_select(Equipment.statuses) %>
    <%= form.submit %>
<% end %>

While we didn’t write any actual HTML here, ActionView takes this template and generates the HTML for us to render back to the browser. Here, we’re rendering a form that allows the user to populate all of the fields our Equipment model currently supports, and posts the information to the correct URL when the user submits the form. We have two selects here – one to allow the user to select which Warehouse the equipment should be associated with, and another for the user to select the proper status description for the equipment. While we’re keeping this example simple, it’s easy to see how we could substitute in a different / smaller collection of warehouses (perhaps based on the current user’s permissions) as this interface evolves. This very basic form comes with a lot of web accessibility baked in for free – the labels we’ve declared in this view are automatically associated with the relevant inputs, and will be populated with human-readable text that can be defined in localization files supported out of the box by Rails. There’s so much more flexibility and power that Rails gives us to quickly build functional, RESTful applications, but hopefully these examples illustrate the framework’s focus on intuitiveness and convention over configuration. Rails’s key feature, and the reason we love it here at TXI, is that we can do so much work with very little boilerplate or repetition.

Ruby on Rails

FAQs

  • Is Ruby on Rails a dead / dying framework?
  • Is Open-Source Software secure?
  • What are the disadvantages of Ruby on Rails?
Ruby on Rails

Terminology

Open-Source
Open-Source” means that the source code for a particular library is publicly available, and typically implies that the project owners accept issues and code contributions from engineers outside of the core / original development team. The vast majority of open-source projects are free even for commercial use, with the most popular software license being the business-friendly and permissive MIT license.

API
Short for “Application Programming Interface,” an API is a set of definitions and protocols describing the ways in which you can interact with a service. It can be used to refer to the actions exposed by a web application, or to the manner in which interactions for objects in a language are exposed.

DSL
Short for “Domain-Specific Language,” a DSL is a programming language or interface created specifically to solve problems in a specific domain or niche. An example would be MediaWiki templates, which define the language used by Wikipedia for the purpose of creating page templates and allowing pages to easily create rich links to other pages.

Greenfield Applications
A greenfield application is one that’s built without any constraints imposed by prior work. Typically, these involve the implementation of a novel business concept and entail a lot of discovery and iteration work in addition to the actual engineering work. For greenfield projects, risks around ongoing maintenance and regression of existing features tend to be low, with the focus being on achieving a marketable product as quickly as possible.

HTTP
Short for “HyperText Transfer Protocol,” HTTP is a standard for transmission of data over the internet. It’s a key foundation of the World Wide Web.

REST, or RESTful
Short for “Representational State Transfer,” REST defines a series of constraints for the architecture of web applications. Among these are the requirement that actions are performed via HTTP requests, and the requirement that the server can understand any request from the client without any knowledge of previous requests. The primary benefit of adhering to a RESTful architecture is predictability––the various possible actions have specific meanings and implications, and web engineers can interface with your application in a standardized and automated way.

MVC
Short for “Model-View-Controller”, MVC is a pattern for structuring web server interactions. Models define the storage layer (how data is validated and persisted in a database). Views define the representation layer (how data is displayed back to the client or user). Controllers define the interaction layer (which actions are possible to take on specific pieces of data and the business logic for performing those actions).

Back-end / Front-end
These terms are used to refer to where a particular part of a system lives. Back-end functionality takes place on a remote server, typically hosted in the cloud. This is where the majority of the business logic lives and where client data is stored. Front-end functionality takes place in the client, often a web browser or mobile application, and provides the interface by which users can interact with a service. Creating a full-stack web application involves building both a robust, secure back end, and an intuitive, usable front end.

Let’s start a conversation

Let's shape your insights into experience-led data products together.