Talks
Making a Rails App with 140 Characters (or less)

Making a Rails App with 140 Characters (or less)

by Nate Berkopec

In the video "Making a Rails App with 140 Characters (or less)" presented at RailsConf 2016, Nate Berkopec explores the modularity and lightweight nature of the Ruby on Rails framework by systematically stripping down a Rails application to its essentials. The session aims to challenge common perceptions of Rails as being bloated and complex, demonstrating that it can, in fact, be simple and efficient. Berkopec guides viewers through the intricacies of the Rails initialization process and the default file structure generated by the 'rails new' command, which initially creates a substantial amount of boilerplate code.

Key points discussed include:

- Common Misconceptions: Berkopec addresses the contrasting views on Rails, suggesting that many negative associations may stem from its extensive boilerplate and perceived complexity.

- File Structure Breakdown: He elaborates on the various folders and files created by the 'rails new' command, outlining which components are unnecessary for a simple application and how they can be removed without losing functionality.

- Creating a Simple Controller: As the demonstration progresses, Berkopec sets up a minimal 'Hello World' application, illustrating the addition of a simple controller that responds with plain text.

- Focus on Modularity: The presentation emphasizes the importance of modularity in Rails, allowing developers to utilize only the components necessary for their applications. Berkopec showcases how to remove unnecessary files and directories, allowing for a more streamlined setup.

- Building a Minimal Application: The process of consolidating the application into five essential files is described, culminating in a functional Rails application that operates with minimal code, highlighting Rails's capacity for efficiency.

Berkopec concludes the talk by stressing that understanding and leveraging Rails's modular framework not only improves performance but also aids in writing cleaner and more maintainable code. He encourages developers to reassess their approach to Rails applications, focusing on what is truly necessary for their projects to enhance organization and resource efficiency. To support further learning, he shares resources, including a GitHub repository related to the presentation and a course on Rails performance optimization.

00:00:10.120 My name is Nate Berkopec. Welcome to the month of May! I'm also known by the name of 'Grand Maester Nate.' I'm an expert in Rails magic. I've forged my links at the Oldtown Great Citadel. Just kidding—Rails is not actually magic. David Heinemeier Hansson (DHH) does not actually sacrifice chickens in his backyard to make all the components work. Today, we're going to talk a little bit about some of that 'magic' and explore the different parts of the Rails framework. We'll examine how they fit together when you type 'rails new' and receive a vast array of folders and files. What are they all actually doing for you? Can we get rid of all of them? Ultimately, we aim to create a Rails application in a tweet!
00:01:38.880 When I mention 'Rails,' what comes to mind? Do you think of it as bloated or lightweight? When you have a Rails application and it spans 50,000 lines, does it feel a bit overwhelming? Do you associate Rails with well-architected code or do you picture spaghetti code? I've heard action controllers described as a 'crack den of inheritance.' When you think of Rails, do you consider it modular or monolithic? Many users on Stack Overflow complain about CSRF protection not working, with common advice being to simply turn off CSRF protection. This observation suggests that people take a rather cavalier approach to security, akin to saying, 'If it breaks things, let's ignore it.' When you think of Rails, do you think of its speed, or do you associate it with slowness? Does your Rails application sometimes feel like it's moving at a leisurely pace?
00:03:39.720 Despite the negative mental associations many people have with Rails, I believe it's a lightweight, well-architected, and modular framework for creating speedy web applications. Unfortunately, it often fails to advertise itself this way. Part of the blame lies with how DHH describes Rails. In his keynote last year at RailsConf 2015, he depicted Rails as a 'prepper backpack' for doomsday, implying that he wanted to be able to rebuild base camp with just Rails, should the internet collapse. This expansive vision contrasts sharply with the simplicity advertised by other frameworks. However, it does not imply that Rails cannot be simple or lightweight.
00:05:01.600 In this talk, we will start with the file structure and boilerplate generated by the 'rails new' command. We will systematically remove the components until we reach a concise application of just 140 characters. The first step after typing 'rails new' is to add a controller. Our app needs to do something, so I will add a 'Hello World' controller that renders 'Hello, World!' in plain text. I also need to add a route for this in the config/routes.rb file.
00:07:02.199 At this point, we have 433 lines of code generated by 'rails new,' spread across 61 unique files. That’s quite a lot, including configuration files and Ruby files. Therefore, our initial step should be to remove all the empty folders and files. Many folders generated by 'rails new' are empty, often included just to force Git to track them. However, Rails doesn't require these empty folders to function. For instance, we can safely delete the entire 'lib' folder, 'log,' and 'temp' directories since these will be recreated when needed. Also, we can delete the 'vendor' folder for our 'Hello World' application since we don't need any assets.
00:08:10.960 Next, we should eliminate all the boilerplate empty files that serve no purpose. Many of the files in the 'config/initializers' directory are just blank with comments that provide no real functionality. They're simply signposts suggesting where to put code without being useful in and of themselves. We can delete the entire 'public' directory, as files like 500.html and 404.html are designed to display error messages but are not necessary for our simple application.
00:09:13.640 My main point is that empty does not equal worthless. One of the most important things that 'rails new' does is create these empty, comment-filled files because they establish a common vocabulary. When starting a new Rails application, you know where to find the domain model business logic, typically in app/models. You can expect the HTTP-related code to be in app/controllers and the jQuery plugins likely found in vendor/assets/javascripts. This structure eases navigation for developers when shifting from one Rails application to another.
00:10:38.680 Moving on to step two, we will delete the entire 'app' folder. Some deletions, like the removal of assets, are straightforward, while components we won't use include 'application.js' and 'CSS.' The actual controller logic will be moved to 'config/application.rb,' and we’ll drop all views and models. Essentially, only the controller remains in a 'Hello World' application. I will eliminate the application controller as well because we don't need a common controller pattern for a single controller application. Therefore, we can place it directly at the end of 'config/application.rb.' If you’re confused about why this is being done, I recommend watching Xavier and Oraz's talk that precedes mine.
00:12:22.600 The next step is to delete the entire 'bin' folder, which contains files aimed at improving development convenience, like 'bin/update' and 'bin/setup.' These files serve as best practice examples for setting up a development environment but can be removed. The other four files—'bin/spring,' 'bin/rake,' 'bin/rails,' and 'bin/bundle'—are simply bin stubs, designed to wrap a gem executable in a bit of environment setup.
00:13:14.680 For our 'Hello World' application, we don't require these bin stubs. Instead, we'll utilize 'config.ru' directly and employ the 'rackup' command. 'Rackup' looks for a 'config.ru' file in the current directory and treats its contents as the body of a block within the code.
00:15:12.680 The 'config.ru' file in a generated Rails application looks quite simple, with a few key actions defined. Essentially, we call the 'Rack' method using our 'config.ru' file, rather than launching 'rails server.' This will execute 'config.ru' directly, achieving the same result without unnecessary overhead.
00:16:21.720 Next, we will only use the components we need from Rails. At the start of 'config/application.rb,' the directive 'require rails/all' loads all the different frameworks in Rails. However, many applications don't actually employ all components, particularly API-only applications. For our Hello World app, we will only utilize the Action Controller framework. The process of modularizing is important to understand, stemming from the merging of a web framework called 'Merb' into Rails to enhance modularity.
00:20:01.559 The Gemfile only needs the 'gem rails' entry. To minimize our application further, we can eventually remove 'bundler,' which, while annoying, technically works. It's crucial to understand that Rails is cautious about what gets included in the Gemfile and the framework itself. Everything in the Gemfile serves as a suggestion and is not mandatory for creating a Rails server.
00:21:36.560 As we strip down the application further, we can discard several configuration files, as they become obsolete when certain components are no longer loaded. By eliminating all the unnecessary files, we can condense our application down into five essential files. Our goal now is to inline these files into one, where we will merge 'boot.rb,' 'environment.rb,' 'application.rb,' and 'production.rb' into 'config.ru.'
00:24:20.360 By performing this consolidation, we'll establish what I consider to be the smallest functional Rails application. Although it may seem contradictory, we accomplish a complete Rails application using only a minimal number of lines. Every 'rackup' file ends with a command to run some rack-compatible application, allowing us to define our application's routes and controllers succinctly.
00:26:18.600 Moreover, all controllers in Rails are essentially just rack applications. This means if you'd like to run the controller as a complete application, you'll organize it within your 'rackup' file. The action method leverages symbols corresponding to respective actions, allowing us to execute the call method on the returned object.
00:29:04.799 To summarize, Rails is a modular framework built upon layers, each component addressing specific functionalities in a Rails application. For instance, ActionController is a direct descendant of ActionController::Metal, which enables you to craft a thin controller. Our final objective is to understand how these pieces all fit together and function as a streamlined web framework.
00:30:05.840 As we bring this all together, remember that not all models need to depend on ActiveRecord. It's perfectly acceptable for objects in the models folder to exist independently, offering a flexible way to utilize ActiveModel for presenting plain Ruby objects that mimic an ActiveRecord-like interaction, without necessitating database persistence.
00:32:00.720 The takeaway here is that this modularity championed in Rails isn't solely for the purpose of performance; understanding how to utilize Rails more effectively can save resources and improve the organization of your code. Try approaching your Rails applications anew, focusing on utilizing only what you need from the framework.
00:39:32.760 Thank you very much for your attention! The full presentation and GitHub repository related to this talk can be found at Nate Berkopec's GitHub, while I also recommend you visit 'railpspeed.com' to explore my course on improving Rails performance.