The Ruby Unbundled Series: Writing an Instant Poll Rails App in a Single File
Tags: ruby, rails, devops, webdev
Published: 2021-03-24 06:56:27

---
title: The Ruby Unbundled Series: Writing an Instant Poll Rails App in a Single File
published: true
description: Build an entire Rails application in just a single file that can be embedded in other web pages or used to implement a microservice.
tags: ruby, rails, devops, webdev
canonical_url: https://blog.engineyard.com/ruby-unbundled-instant-poll-app-in-single-file?utm_source=dev.to&utm_medium=canonical-link&utm_campaign=top
//cover_image: https://blog.engineyard.com/hubfs/RackUnbundledImageOnly.png
---
By [Darren Broemmer](https://blog.engineyard.com/author/darren-broemmer)

### __How to create a single-file Ruby app__

Ruby-on-Rails generates a lot of artifacts when you start a new application. Just typing rails new app_name gets you started quickly. It's an opinionated way to implement a web application. The good thing is that any Rails developer generally knows where to look for things. For example, I know that images are going to be located in the app/assets/images directory.

However, in a lot of cases, you actually don't need many of the generated artifacts. If you take a look at the app directory structure, there's a vendor directory, a storage directory, and other nested directories you likely may not use.

Thanks to some pioneering work by [Nate Berkopec](https://github.com/nateberkopec/rails_lightweight_stack) on lightweight rail Stacks, we can pare down the rails application to the absolute bare minimum and make it a lot simpler. Take a look in your rails application directory and you’ll see a file you probably haven't paid much attention to, config.ru.

The config.ru file really just runs your Rails application. The extension is short for rack up. Here is the default version that came with my app.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bv7feaqx517v3dnkdyeq.png)

So what is [Rack](https://rack.github.io/)? Rack sits between your Rails application and your web server, puma in my case. It provides an abstraction that allows you to swap out the web server if you like. It performs quite a bit of request handling logic.

To see what it's actually doing, run the rake middleware command. This command will take a moment to run, but it will list all of the different handlers that every request to your application goes through. This includes things like logging, exception handling, and session management. There is a lot of good stuff in there which fortunately, you generally don’t have to think about.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p99eeh4uvs2t5vj2qljv.png)

Now, if you are thinking that the config.ru file appears to be the equivalent of a Java main function, you are correct. It gets your Rails app started and pulls in artifacts from your config directory, for example environment specific information and secrets. It starts your web server process and wires up routing to your controllers.

__Simplifying our App__
We are building an instant poll application that we can embed into a larger page. We want the code to be as compact as possible. The end result looks like this.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c7yc6417b40wx0ndnjdw.png)

The primary components are shown in the diagram, however our goal will be to condense all of this into the config.ru file.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q26os9dkrxlgvxzjql0d.png)
For our purposes here, we store the poll results in memory as opposed to a database. That allows us to get rid of our model classes. As for the view component, we don't have to separate that into its own file. We do lose the ERB templating feature, but we can render HTML directly from the controller.

The controller class definition moves to the config.ru file, and we inline only the necessary configuration elements. We are down to one file now! Here is the start where we extend the Rails application and we set only the absolute required configuration elements. There is only a single URL which handles the initial GET and the form POST. We need to set the X-Frame-Options header to allow our application to be embedded into other web pages.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t86p5yv03cto1e6wsfsi.png)
Our inline controller looks to see essentially if this is the view of the pool or a submission. On a submission, it keeps track of the counts and renders the results in HTML Otherwise the form itself is displayed. We have 76 lines of code, with most of it actually being the HTML.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pbzlwqs652o8mi4j0s5r.png)
At the very end, you have the app initialize and run statements that you would find in a typical default version of this file. Finally, we run our app using the command bundle exec puma -p 3000

After a few submissions, the results look like this.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jut4c6uqs0e3gkadmhd.png)
This is a pattern you can use to implement embedded apps or microservices. We built our instant pool app in 76 lines of code on Rails 5.2. Aside from the HTML stuffed into the controller class, it's actually somewhat elegant. The complete code for the Instant Poll app can found here, 

Hope you found this useful and let us know what micro-applications you are able to build on Rails.

Related topics
[Software Architecture](https://blog.engineyard.com/topic/software-architecture), [Ruby on Rails](https://blog.engineyard.com/topic/ruby-on-rails), [developer productivity](https://blog.engineyard.com/topic/developer-productivity)
*****
[Originally appeared on engineyard.com](https://blog.engineyard.com/ruby-unbundled-instant-poll-app-in-single-file)