The Guide to Cuba, a Ruby Micro Framework


The Guide to Cuba

This book is a work in progress and is licensed under the CC BY-NC-SA 4.0 license .

1. Introduction

The Guide to Cuba will teach you how to create a Ruby web application from scratch using Cuba. Cuba is a micro framework written by Michel Martens ( @soveran ). It is open source, and you can have a look at the code here .

Some Ruby frameworks can be bloated and offer functionality you don't need. We'll teach you how to use Cuba together with small and simple Ruby libraries to customize your stack. By applying this minimalist philosophy you achieve more flexibility, less complexity and maintainable code.

Here's a list of pages that uses Cuba for inspiration:

AT&T’s M2X Educabilia openredis Redis homepage 2. Assumptions

This book is intended for anyone who wants to get started with Cuba. It's recommended to have some basic knowledge of the Ruby programming language. If you're unfamiliar with Ruby, or would like a refresher, we encourage you to take this tutorial to get up to speed: .

In order to try out the examples of the book, you need to have some prerequisites installed:

Ruby 2.0 or newer. You can get the latest Ruby from the Ruby download page .

The Redis database. If you don't have Redis installed, you can follow the instructions in the Redis download page .

You can find the code exampleshere. They have all been tested on OSX and Linux.

3. Setting Up the Project

By following the next chapters, you are going to build a Twitter clone called Frogger .

The first thing you need to do is to create the project folder. You can create it by writing the following command in your terminal:

$ mkdir frogger

Afterwards, switch to the project folder:

$ cd frogger

NOTE: From now on, all the command line instructions shown in this book must be executed in this directory.

4. Up and Running

This first chapter focuses on the bare minimum you need to know to work with Cuba. We'll learn some of the core concepts and walk through the creation of the classical "Hello World" application.

4.1. What's Cuba?

Cuba is one of the lightest options when it comes to web development in Ruby. Here are some core attributes that are worth mentioning:

It's incredibly small, less than 200 lines of code. This simplicity by design makes Cuba easy to understand and debug, and very stable (no major changes since 2012).

Like most web frameworks in Ruby, Cuba is built on top of Rack, a Ruby webserver interface. Because of this, we have the benefits of existing libraries and a variety of web servers for free. Don't worry if you don't understand what Rack is just yet, we'll discuss it later.

Cuba does one thing and does it well, handle HTTP requests. This gives us the freedom to choose the appropiate tools for the job at hand. This book will introduce other libraries that share the same design philosophy.

It is fast? Yes, it is .

4.2. Hello Frogger!

To get started, use the gem command to install Cuba:

$ gem install cuba

Now that Cuba is installed, it's easy to create an application. Open your preferred text editor and create a file called app.rb with the following code:

require "cuba"Cuba.define do on root do res.write("Hello Frogger!") endend

Then create another one called with the contents shown below:

require "./app"run(Cuba)

You already have a functional Cuba application! To see it in action, you need to start a web server. You can do this by typing rackup in the command line.

NOTE:To stop the web server, hit Ctrl+C in the terminal window where it's running. To verify that the server has stopped you should see your command prompt cursor again.

Now open the browser and navigate to http://localhost:9292 to see the greeting message:

4.3. Breaking Down the Syntax

Now that you know how to build a minimal application, let's take a deeper look at the syntax.

First, you load the Cuba gem to access its functionality.

require "cuba"

Then you can see four methods that appear in most Cuba applications:

Cuba.define do on root do res.write("Hello Frogger!") endend

define allows us to create an application through a block.

on executes a given block if the passed conditions evaluate to true .

root returns true if the accessed path is the root of the application ( "/" or "" ).

res handles the server response. In this case, you use the write method to set the response body with the greeting message.

When you enter http://localhost:9292/ , the application checks if the accessed path is the root. Since this evaluates to true , it prints "Hello Frogger!" .

4.4. Introduction to Rack

As we mentioned earlier, Cuba is built on top of Rack ... but what is Rack?

Rack deals with HTTP requests. It provides a minimal interface between web servers supporting Ruby and Ruby frameworks. Without Rack, Cuba would have to implement its own handler for each web server.

To run the hello world application you used rackup , one of the tools that comes with Rack.

To use rackup , you need to supply a file. This file connects the Rack interface with the application through the run method. This method receives an object that returns a Rack response. In this case, that object is the Cuba application:


rackup also figures out which server you have available. When we use rackup , it fires up WEBrick , a web server built into Ruby by default.

$ rackup[2014-05-06 23:37:23] INFO WEBrick 1.3.1...

You can read more about Rack visiting their home page: .

5. Managing Dependencies

In every web application, there are common tasks that you need to perform (e.g authenticate users or query a database). Libraries are useful for not reinventing the wheel, and in Ruby they are often referred to as gems .

Ruby uses Rubygems to distribute them and to ease the installation. Installing Cuba was as easy as typing gem install cuba in the command line.

Even though Rubygems is useful when installing gems, it has its limitations. Unfortunately, it installs all gems globally. This means that if you have different versions of a gem installed, you have to make sure that you require the right version for your project.

We need a way to keep track of the dependencies and install the right version of each one. This is where tools like gs and dep come to the rescue.

5.1. gs

With gs you can create a gemset for each project. A gemset is an isolated space to install gems. By providing each project with its own gemset, you can be sure that the right version of a gem is loaded.

To install gs, do:

$ gem install gs

Creating a new gemset is as easy as typing:

$ gs init

This command creates a directory .gs and starts a shell session. In this session, all gems will be installed locally in the .gs folder.

5.2. dep

Now that we created a gemset, you will use dep to keep track of the project dependencies.

dep uses a .gems file to list the required gems with their version number. This file will be created automatically the first time you add a gem to the list.

To add Cuba to this list, use:

$ dep add cuba

This fetches the latest version of the gem and adds it to yours .gems file. Let's see what the file looks like after adding the Cuba gem:

cuba -v 3.3.0

To install the listed gems in the .gs folder, do:

$ dep install

To check that they're installed, use:

$ depdep: all cool

If all is cool, you're good to go!

6. The Application Homepage

It's time to replace the greeting message with a nice homepage. To do that, we need to change the code to return HTML. It can be written like this:

Cuba.define do on root do res.write(" <html> <body> <!-- ... --> </body> </html> ") endend

This approach can get very messy, especially when you need to generate content dynamically (e.g. a user's timeline), or parts of the HTML are repeated on every page (e.g. a navigation menu). Therefore we separate it into views , which are template files that get converted to HTML and sent back to the browser.

In this chapter, you'll learn how to use mote , a minimal template engine to render views.

6.1. Mote

Mote is a fast template engine that allows us to put Ruby code into any plain text document, like HTML.

Mote recognizes two tags to evaluate Ruby code: % and {{}} . The difference between them is that while the % tag only evaluates the code, the {{}} tag also prints the result to the template.

Imagine that your template looks like this:

% gems = ["rack", "cuba", "mote"]<ul>% gems.sort.each do |gem| <li>{{ gem }}</li>% end</ul>

The generated result will be:

<ul> <li>cuba</li> <li>mote</li> <li>rack</li></ul> 6.2. Mote & Cuba

Use the dep command to install the mote and mote-render gems.

$ dep add mote$ dep add mote-render$ dep install

NOTE: Remember to install the gems inside of the shell session instantiated by gs. You can instantiate it by typing gs in your terminal.

The mote-render gem includes a plugin called Mote::Render . This plugin tells Cuba where to look for template files and uses Mote to render them.

To set up Mote in the application, change the code as shown below.

require "cuba"require "mote"require "mote/render"Cuba.plugin(Mote::Render)Cuba.define do on root do res.write("Hello Frogger!") endend