September 14, 2023

Benefits of using Ruby on Rails for creating digital products

Jordan G. Trevino

Founders or businesses looking to create a startup which depends on a digital platform must consider alternatives for how to create their main web platform, and the bulk of the business logic it handles. Examples are many: Airbnb had to create an experience for showing short-term listings as for users to reserve these. Lira had to create a benefits and payroll management product and the logic to calculate and produce payroll payments and receipts. 

Such interactions depend on many variants of the same thing: creating, reading, updating and deleting digital resources. A digital resource is the digital shadow of a real-world resource. You can’t book an Airbnb listing if the actual apartment or house isn’t digitized. Similarly, companies can’t make payroll on Lira for their team members unless the company and each employee are set up as digital resources on their web platform. This pattern is so common that it is known as CRUD for Create, Read, Update and Delete. For example, an Airbnb listing must be created, read as a user browses it, updated when the host changes the listing, and eventually deleted. These all rest on the technology of a database-backed website.

Most web development can be conceived of as an interlinked network of different objects with web flows which at times create, read, update and delete resources linked to a database. Want to make an Airbnb reservation? That’s a create. Want to see a listing? That’s a read. And so on.

Ruby on Rails, and other full-stack frameworks accelerate web development

CRUD web development is not a novel problem. It is a significant amount of work to rebuild a programming environment over and over simply to allow for this kind of manipulation of digital resources. Yet without a web framework to assist, any team will be faced with just this challenge. A better alternative is to use Ruby on Rails, or frameworks like it, which abstract away the common tasks faced by all web applications so that teams can focus on what makes their product unique. In the Rails community, this has also been called “complexity compression”, as shared by Rails creator David Heinemeier Hansson (or DHH) in a RailsConf keynote entitled FIXME in 2018.

By working with Ruby on Rails, companies like Airbnb, Shopify and Lira simplified their own development work by not reinventing the wheel of basic web development, giving themselves clear best practices, and having the option of tapping the deep ecosystem of shared packages and expertise.

Some companies that use Ruby on Rails include Airbnb, Basecamp, Dribble, Fiverr, Github and others.
Some companies that use Ruby on Rails include Airbnb, Basecamp, Github and others

Source: https://railsware.com/blog/famous-web-apps-built-with-ruby-on-rails/

Let's discuss some highlights of some of the benefits of working with Ruby on Rails:

  1. Convention over configuration
  2. Best-in-class interface for handling database-backed data
  3. Powerful and versatile front-end with cutting-edge patterns
  4. Outstanding quality ecosystem
  5. Thriving community and open-source packages 

1. Convention over configuration avoids complexity bloat

A strong Convention over Configuration organizing paradigm which leverages object orientation and applies it to routes, models, controllers and views. This provides a “just works” feel about Ruby on Rails, that saves the developer from having to explicitly configure connections between obviously related components of a Rails application. For example, a route defined for “posts” will tell the application by default and without any specific configuration to map the requests to a “PostsController.” Specific HTTP verbs are mapped by convention to actions on the controller. In this case, for example, the GET method made to the posts will be received by the index action of the PostsController. So in many cases, as long as a developer follows naming conventions Rails is designed to work with, the magic of the framework just happens.

Many other programming environments such as Node are too open-ended and require that development teams painstakingly configure the tooling for their needs. Over in JavaScript land, Node requires additional frameworks like ExpressJS and other middlewares to do basic web development. Yet their docs even explicitly warn would-be users of the dangers and pitfalls of getting started on this path, and I quote:

There are middleware packages to address almost any problem or requirement, but working out the right packages to use can sometimes be a challenge. There is also no "right way" to structure an application, and many examples you might find on the Internet are not optimal, or only show a small part of what you need to do in order to develop a web application.

Source: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction

As companies grow and incorporate less experienced team members, this lack of pattern in other frameworks can be a significant pain point. Rails avoids this to an extent with its clear conventions. There is no ambiguity about the basic structure of a simple Rails application. It requires no extensions and no add-ons for simple web development. This is a considerable advantage.

2. Rails provides a best-in-class interface for handling data

A good user-experience to the database layer is a core benefit of Ruby on Rails. Before Rails, the relational database required more specialized handling. For years, these duties were handled by a DBA or database administrator. Specialized database attention can still crop up for challenging problems or more specialized needs. Yet for standard web development, much of the complexity has been compressed away such that a focused DBA isn’t needed. The main innovation is the widespread use of an object-relational mapping between Ruby classes (the model in the Model, View, Controller framework) and database tables which lets the developer handle queries and inserts in idiomatic Ruby — without writing any SQL directly. This gem is called ActiveRecord, and is one of the core elements of the Rails framework.

The Rails approach to the database layer has been so successful that it has been effectively adopted in most web frameworks available. These practices are similarly powerful in frameworks built on Python and JavaScript. Yet the constant enhancement and advancement of the functionality reality pays off and is especially notable in the Rails community, with a widespread group of large-scale and small applications as well as a committed core of maintainers and visionary leaders for the framework. 

For example, at Telos, we recently led a project in which we built a Rails monolith to accelerate a client delivery over the Node microservices approach previously used by the company. To leapfrog building an API-based data exchange (because this was an API we wanted to eventually eliminate), we created a new Ruby on Rails application connecting the models to specific databases. This was necessary because the microservices approach had distributed important and related data across different databases. Fortunately for us, with Rails 6 Eileen Utichelle provided Rails the ability to support multiple databases. See her keynote at Railsconf here. Thanks to Eileen, our work was much easier than it would otherwise have been and we were able to reconstruct a monolith by connecting the Rails app to nearly 10 separate databases, depending on the model in question. (As an aside: The project was so successful that it became the basis for the new approach used by the company to accelerate their web development for their flagship product. The company has now IPO-ed.)

3. A front-end capable of server-side rendering and API-focused patterns

Web-development is currently beset by struggles over the optimal way to render the front-end. The discussion tends to center around what flavor of single-page app to use (React, Vue, Angular, etc.). From a Rails perspective, the debate is moot, because Rails supports all these patterns. Yet it even goes beyond them by offering something much more effective and efficient: the return of server-side rendering while delivering an experience comparable to single-page apps.

If you prefer to take-on the additional complexity of a separate single-page app on the front-end, Rails views are limited to providing structured data (typically JSON) as part of a REST or GraphQL API. You can then add your single-page app to the Rails app, and it can be served as part of the Rails application — or it can be separately deployed and served outside of the Rails application. Whether you use React, Vue, Angular or anything else — they all need back-end data and back-end operations. And so Rails can fulfill the role of providing the back-end.

Yet the more intuitive way of building your application front-end, leveraging Rails capabilities fully, is by building out your front-end as HTML templates directly inside the application. This reduces complexity because you end up with one full-stack application instead of two (back-end and front-end). The complexity reduction you gain from that is very significant — as you avoid having to manage state and coordinate their changes between one app and the other. In a Rails server-side rendered application, features can be developed quickly and with lower risk of errors. Additionally, new practices including Turbo and Hotwire make a Rails server-rendered app look and feel like a single page application. So you get a similar experience, with much less effort, and therefore lower investments in money and time.

4. Outstanding quality ecosystem

There are still large parts of the internet, and especially corporate-run digital services, that get away with painstaking manual testing whenever new changes get released. Fortunately, the Ruby on Rails world has always been driven by creators and business founders, over corporate managers. This means that from its very early days, the framework has been accompanied with an expectation of automated testing as part of competent feature development. Over time, any project following this convention will accumulate thousands of tests, or “specs” which can easily be configured to run on every batch of code changes (also known as a pull request). What this accomplishes is a tremendous benefit by default: the execution of a regression testing suite that enforces high quality standards.

Not only that, the specs run by Rails also favor idiomatic English which gives the application documentation by default, and supports a common-sense understanding of what is going on over a slide towards arcane minutiae, as sometimes happens when technologists get together. If the team is well coached and disciplined to ensure that specs are created as part of the development process, and they are wise and understanding of the risks and possible failure scenarios for any given feature so that the specs adequately address these risks — your application will be in great shape. 

For example, see a few specs written in Ruby code, and using the rspec library. This is just a small part of a test suite of an application we manage at Telos. The code below defines some association expectations (these associations are part of ActiveRecord’s library, and allows us to easily fetch associated records in another table. Further below, we test two key capabilities: 1) the ability to call `next_question` on a survey_question, and, 2) the ability to correctly determine whether the question was `completed_by_user?`. 

RSpec.describe SurveyQuestion, type: :model do  
 describe "associations" do    
   it { is_expected.to belong_to(:survey) }    
   it { is_expected.to have_many(:options).dependent(:destroy) }    
   it { is_expected.to have_many(:answers) }  
 end
 describe "methods" do    
   before(:each) do      
     …core logic here…    
   end
   context "when next_question is called" do
     it "returns the next question in order" do
       expect(@fh_survey.questions.first.next_question.order).to be 2      
     end
   end
    context "completed_by_user?" do      
     it "returns boolean indicating if question has an answer" do        
       expect(@fh_survey.questions.first.completed_by_user?(@user, 1)).to be true
       expect(@fh_survey.questions.last.completed_by_user?(@user, 1)).to be false      
     end    
   end  
 end
end

The above code yields the following output in green when run to show they have successfully passed. If any of the specs fail, they are shown in red and displayed as part of a summary at the end of the test execution.

SurveyQuestion
methods
 when next_question is called
   returns the next question in order
 completed_by_user?
   returns boolean indicating if question has an answer
associations
 is expected to have many options dependent => destroy
 is expected to have many answers
 is expected to belong to survey required: true

These specs run each time a developer wishes to make changes to the application, through an automatic process we’ve set up as part of our Continuous Integration. The results of the specs are saved for future auditability on Github, and we only merge code changes where all specs pass. I hope this shows how easily the Rails ecosystem supports high-quality software development, but there is more. Additional libraries easily allow testing to span the front-end, and run tests by loading up the browser interface. This helps round-out our quality approach with end-to-end integration tests.

5. Thriving community and ecosystem

More than 6,000 people have contributed to the Rails framework. Yet beyond just the framework, there are countless libraries (which we call gems in Ruby land) which help address many features and use cases. This means that building on Rails, you will be able to focus mainly on writing the custom business logic that makes your domain unique and difficult, rather than on implementing the same feature over and over again. Let me give three examples: authentication, asynchronous jobs, and admin panels.

Authentication is the main feature protecting your application from the threats of the outside world. It makes sure that your users are able to gain access to their data, and that no other person or agent can. Given the tremendous importance and sensitivity of this feature, you’d better get it right. Do you want to spend the months to devise a custom authentication flow that is robust and secure? I hope not. That is why most everyone in the Rails community uses the Devise gem. It covers all the flows you are likely to need: standard registration and login, email confirmation, password resets, locking-out functionality if there are too many failed attempts, and so on. This technology has been around since 2009 and has many contributors, getting more and more hardened over time. And if you want even more functionality, there are tens of extensions available for it.

Asynchronous jobs: Ruby is single threaded, which means that intense computations need to be run in a separate process, or else they will block any response for the user. The Ruby on Rails community solves this problem by running an asynchronous job queue, which will be processed separately from the web server which responds to user requests. This is not a trivial matter. You could find yourself buried deeply in queue processing logic if you had to implement this directly. Fortunately, Rails provides an interface for queue management called ActiveJob, and Mike Pernham from the Rails community has created Sidekiq — the leading asynchronous job queue used by nearly all Rails applications which have a need for this functionality. With Sidekiq, you get a robust, simple and efficient engine to background process your jobs. 

Admin panels are a key capability of nearly all web applications. No matter the domain, at some point, some team member will have the interest and responsibility of managing the functionality and taking some required administrative actions. Building admin panels from scratch would be a significant waste of effort, because so many of the capabilities are the same across admin panels (simple presentation and editing of data, downloading of csv exports, filtering data, adding comments to certain records and so on). For this reason, it is a better idea to use one of the several good admin panel gems out in the community. Some of the good ones include: ActiveAdmin, Administrate, and RailsAdmin.

There are just a few examples of open source packages which make developing in Ruby on Rails significantly faster and more efficient than other environments with a less active and generous community. This is all part of the ethos that makes the Ruby on Rails framework and community special: at heart, it has always been about encouraging happy development, as we revel in the capabilities of good craftsmanship, and the elegance of our weapons in building something novel in the world. For further readings on the philosophy behind Rails, and what makes it so unique, read the Rails doctrine.

READY FOR
YOUR UPCOMING VENTURE?

We are.
Let's start a conversation.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.

Our latest
news & insights