The best way to create a solid software application today is to make it based on different modules. This makes your software well-structured as each module can be tested and configured separately, while the software application itself can be easily removed or installed. Ruby on Rails is an open-source Web application framework that provides us with the power of Web software development using “gems”. Gem in Rails refers to a plugin that carries additional functionality or simply extends Rails engine.

So what should you know before starting to write your Gem?

  • Ruby on Rails knowledge – if you still don’t know what it is you should start learning now
  • Check if there is an existing gem you can use (perhaps it will save you the work of writing your own)
  • Plan the exact purpose of your gem – this could be the hardest part

When you’re done go to your terminal and type rails plugin new your_gem_name – the usual “rails way”.

How did I create my very first gem? Here is the gist: let’s say its name ‘foo.’ Foo will be adding some view helpers, controller and some JavaScripts to my existing rails project.

Running rails plugin new foo gave me a basic directory structure generated for my first gem. What I love about it is that it also has a dummy application with rails for testing purposes. Here’s what I did, step by step:

The first thing I did was edit the foo.gemspec file to add some description about my gem, so before you publish your own gem, be sure to edit it.

The next step involved writing some code. After searching the Web for ways to create my gem, I learned that it can actually have similar directory structure like the one a simple rails application has. It was great finding out that it is so simple.

Now I started writing the main module for my gem, located in lib/foo.rb. The best way to create any software is to make it fully customized. Ruby on Rails projects have initializers where programmers can define variables for gems. As mentioned earlier, I had to add my controller and the first thing I thought about was creating a customizable path for it such as: http://localhost/path_to_controller/action. The variables I have added contain a default value in the main module with config setter method and getter for namespace.

module Foo
  mattr_accessor :namespace
  @@namespace = :foo
  
  def self.setup
    yield self
  end

  def self.get_namespace
    @@namespace.to_sym
  end
end

Next step was to create the controller. I created a file “lib/foo/controller.rb” containing the class FooController under module Foo. I defined a test method for my controller to check that everything was done right and working properly.

module Foo
  class FooController < ::ApplicationController
    def test
      render text: 'Foo WORKS'
    end
  end
end

After that I edited the main module of my gem to let it autoload my controller. I added this line on top of the module:

autoload :FooController, 'foo/controller'

The last thing you need while defining your controller action is to add route for it. As I told earlier gem is like a Ruby on Rails application, so the right way is to create config/routes.rb file, and mount my controller under my customizable route.

Rails.application.routes.draw do
  scope "#{Foo.get_namespace}" do
    match 'test' => "foo/foo#test"
  end
end

This code takes the namespace defined for my gem on the initialization of the rails application and makes it a route to my controller. Defining actions is like a simple action adding in common rails application.

Finally, I've reached the point where I can test everything created until now. I went to the test/dummy directory and executed rails s, then on to the browser and from there to http://localhost:3000/foo/test and it showed me "Foo WORKS.”

Now I wanted to test my customizable path. I created the file test/dummy/config/initializers/foo.rb with the following content:

Foo.setup do |config|
  config.namespace = :boo
end

As expected, producing a new configuration from initializers requires restarting the rails application, so after running back rails s I tested the new route http://localhost:3000/boo/test - and it worked.

Another way to test if the routing works properly was to run rake routes, which printed routes that were set for dummy application.

All this, in a nutshell, was the beginning of writing my first gem. Being part of the development team at CommPeak, the wholesale voice termination provider involves gems of all sorts. In Part 2 I will discuss how to add your own view helpers and JavaScripts to existing rails project with your gem.