In this post, I want to introduce you to Cuba. Cuba is a microframework for web development originally inspired by Rum, a tiny but powerful mapper for Rack applications. It integrates many templates via Tilt, and testing via Cutest and Capybara.
Usually, when you speak to a Ruby developer, he will describe himself as a Rails developer, and his entire Ruby experience might be through Rails. But I think it’s healthy to push yourself out of your comfort zone.
Why should I use it?
I would use CUBA if I needed to create a small web application where I didn’t need Active Record[KEM1] , mailers or any other functionality included in Rails. For a small web app like that, Rails would just be overkill. And also, as I wrote above, it’s healthy to learn something new.
Cuba was created using a minimalist philosophy, only providing what’s needed instead of the long feature list that comes with much larger frameworks. That is why the tagline for Cuba is “Ceci n’est pas un framework,” which translates to “This isn’t a framework.” Cuba was created by Michel Martens.
Let’s create a small “Hello World” app using the router provided by Cuba.
# app.rb require "cuba" require "cuba/safe" Cuba.use Rack::Session::Cookie, :secret => "__a_very_long_string__" Cuba.plugin Cuba::Safe Cuba.define do on root do res.write("Hello World!") end end
And now to test it, we need to create “config.ru” file
# config.ru require "./app" run Cuba
We can rackup and check to see if it worked.
Here are just a few lines of code, but they are surprisingly powerful. As you can see, the on method looks for a case that returns true; and in this case when we open / or root, it yields the block of code and returns “Hello world.”
The block of code has access to res, which is a Cuba::Response class. When you read the documentation, you can see that there are several options; this is the simplest example.
For the view layer, Cuba has a “Cuba::Render” plugin that allows you to use “ERB” templates by default. If you want to use something else like Sass, HAML, or CoffeeScript, I would suggest you look into gem Tilt.
As an example, let’s create a small view file using the method render.
require "cuba" require "cuba/safe" require "cuba/render" require "erb" Cuba.use Rack::Session::Cookie, :secret => "__a_very_long_string__" Cuba.plugin Cuba::Safe Cuba.plugin Cuba::Render Cuba.define do on get do on "todo_list" do render("todo_list") end end end
To make this work, we need to create a layout file.
<!DOCTYPE html> <html> <head> <title></title> </head> <body> <%= content %> </body> </html>
Finally, we need to create our actual view file.
<h1>Create Your Todo List</h1>
And that’s it! Now you can start up your app and go to http://localhost:9292/todo_list to check the result.
What about models and controllers?
As an everyday Rails developer, when I created a web app using Cuba for the first time, that was my question as well. With Cuba, what would usually go into a controller for Rails, goes straight into the router. Or, if you are in need of a model, you can use “ActiveRecord” or whatever you like. It’s your choice.
I like to work by TDD. I can’t imagine working without tests. And I think it’s great that Cuba has built-in support for writing concise, clean code for tests.
require "cuba/test" require "./todo_list" scope do test "Homepage" do get "todo_list" follow_redirect! assert_equal "Create Your Todo List", last_response.body end end
As you can see in this example, we make a request, follow the redirect and check the response. In this case, it’s enough, but for larger apps, you will probably need something more.
Before creating a real web app using Cuba, I would strongly suggest you write down what you really need. Cuba will be great for you if you need to create an API where speed is critical. I was a bit surprised at how fast it works. Cuba is close to Rack, with very low overhead. If you like to keep full control over the entire stack, it will be just in time.
Just keep in mind that there are several other microframeworks; for example, Roda is basically a for from Cuba. Maybe you will feel more comfortable using it; just try it.