Shoes Meets Merb: Driving a GUI App through Web Services in Ruby

Ruby on Rails has helped launch the Ruby programming language into stardom, and for good reason. Rails opened many eyes to the power of Ruby and made web programming that much easier. But one of the unfortunate aspects of Rails is that it tends to color Ruby as a language primarily for database-backed web applications. Some software just doesn't work well in that mold. Additionally, the extreme popularity of Rails has left some Rubyists in the corner wondering what happened to the other great software written in their language. It hasn't gone away; on the contrary, there are a tremendous number of open-source Ruby projects under development. We are going to look at two of them here.

The Merb web framework, written by Ezra Zygmuntowicz, was first popularized as a lightweight way to handle file uploads for Rails applications. It has since grown to become an excellent framework in its own right for creating web applications. It is simpler and seems to be faster than Rails, and it is more flexible in some ways. While Rails is deliberately "opinionated software," Merb acknowledges that there are different options for object-relational mapping systems and web template engines, and does not try to pick one over the other.

If Merb is a paragon of professionalism and class, Shoes is a monkey on LSD. Shoes, by why the lucky stiff, is an incredibly compact cross-platform GUI toolkit for Ruby, but it looks nothing like the other cross-platform toolkits out there. For one thing, it is lightweight. Shoes lets you build GUIs in Ruby whose code actually looks like Ruby, not XML or Java. Shoes is under heavy development right now, but it will eventually form the basis for the new Hackety Hack, _why's programming environment for kids.

So, what are a web framework and a GUI framework doing together, you might ask? We are going to build a pastebin as a repository for our own code snippets and pieces of text we want to save. We'll build a GUI frontend using Shoes, and connect it to a Merb backend that will handle the database. We could just as easily slap on a web interface to the Merb application as well, but we will use the Shoes GUI to demonstrate the ease with which we can connect the two components using Ruby. In fact, the basic proof of concept took the two of us about an hour to get working, and it took another hour to finish.

Without further ado, we present our pastebin application, using Shoes and Merb, Shmerboes.

Creating a Simple YAML-Based Web Service with Merb

Though a lot can be said about Merb being a potential Rails-killer, we're not going to attempt to be so dramatic here. Instead, we'll let Merb speak for itself as we create the server side component of Shmerboes.

Configuring Our Merb Application

We'll start by creating our application skeleton and putting together a simple model that has the bare minimum fields we'll need.

Before we can generate our models, we need to specify the ORM we wish to use. For familiarity and simplicity, we're going to use ActiveRecord, so we need to uncomment the following line in config/dependencies.rb:

use_orm :activerecord

If you don't already have it installed, you'll need the Merb ActiveRecord adapter, which you can grab via:

gem install merb_activerecord -y

You may have noticed when you looked in the dependencies file that Merb offers you some other ORM choices, in fact, Sequel and DataMapper are supported out of the box, so long as you install the appropriate adapters. If you're tired of the "Railsy" ORM feel, you might give one of these a try, but for now we'll stick with the conventional approach.

Once we have our ORM specified, we can set up our database configuration. By running the merb executable, a database.sample.yml file will be created. This serves as a template for your for your database.yml configuration. To keep things nice and easy configuration-wise, we skip over the default MySQL configuration and use SQLite:

You'll notice that, like Rails, Merb generates test files for your models. However, the defaults are a bit different. Merb will use RSpec by default instead of Test::Unit and it also does not automatically generate fixtures. You can of course tweak these defaults if you'd like, but avoiding fixtures and using RSpec are two things that'd generally make a lot of Rubyists happy, so they tend to be decent defaults. At any rate, we won't be focusing on testing in this article, so we leave further tweaking with this as an exercise to the reader.

Now that our Paste model is generated, we need to populate our migration with the appropriate field definitions. As you can see above, this file was generated for us as schema/migrations/001_add_model_pastes.rb. Below is the migration we're actually using:

Great! This tells us we can access our model and that it is wired up to the database. We can now begin on the real work, which is implementing a controller that exposes a simple web API that our shoes client will interact with.