How to Build a RubyGem from Scratch
This guide takes a step by step approach for how to build a RubyGem completely from scratch and how to integrate it into a Rails 5 application.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In the last guide we built out the functionality that we're looking for here. We created a renderer inside of a devcampViewTool module and it generates an HTML copyright and takes the name and updates the year. Let's talk about how can we get this into a gem. We're going to follow along and start building out all of the different components that are needed and that I find helpful whenever I'm building a gem myself.

Let's switch to the terminal, I have created a directory called creating-a-ruby-gem. You can name yours whatever you would like, you could put on the desktop if you want. CD into the new directory and this is how you create a gem.

First, you need to have bundler installed, if you're following along in the scores you should have already done that. I want to say bundle gem devcamp_view_tool. Yours might be your last name followed by a view tool or whatever you want to call it. Another popular convention is to do something like a view tool and then after that Devcamp and append it. The most important thing is that you have some way of designating it to make sure that it's not going to have any name conflicts,

Come to google chrome and go to rubygems.org and you can test it out by inputting your gem's name and hitting search, this will alert you if there is any conflicts.

Switching back the terminal, hit enter and this is going to create all of the files necessary for creating a gem. Pull up the directory/gem in sublime text, there is all kinds of files. By default it gives us a .gitignore file and it creates a git repo for us.

If you look back at the terminal you can see that it says initializing git repo and passes in the path. That means we don't have to type in git init ourselves, it already did that for us. You really need to use git in order to build gems in out.

With all of this in place, open up your gemspec, it's at the root of the directory and has a lot of pre-configured items. One thing that you will notice, it has some TODO items. This is very important, there are some validations that the gem generator did. If we tried to create a gem and we did not change each one of these items, the gem would not compile and we wouldn't be able to use it. It just protects us and makes sure that people recognize that this is here and that it needs to be updated.

Here is a list of TODOs

  • summary
  • description
  • homepage

We're going to delete this entire block (lines 17-24). This prevents pushing this gem to rubygems.org, we want to push the ruby gem. Now come in here and simply type in the information for each TODO.

As you can see I added a summary a description and then the homepage. One thing that I want to be very careful with, notice how I never say the words "view helper" I did that on purpose. View helpers in rails are very specific components and what we're doing here isn't really a view helper. We could technically call this from within a view helper, however, this is simply giving us the ability to generate HTML and so I don't want to name it improperly.

We can come to devcamp_view_tool.rb and you look you can see "require "devcamp_view_tool/version." The first thing that this requires is the version. If I come up to devcamp_view_tool/version.rb, this is where the logic for our gem is going to reside. You can see by default it has a constant variable here that is set to 0.1.0. I'm not going to change that.

We need to import our other file, in the devcamp_view_tool.gemspec, lets say require "devcamp_view_tool/renderer". Now we simply have to go create this file. Right click on in the directory and save renderer.rb now we can copy and paste our code from our portfolio app.

module DevcampViewTool
  class Renderer
    def self.copyright name, msg
      "&copy; #{Time.now.year} | <b>#{name}</b> #{msg}".html_safe
    end
  end
end

This is going to be our renderer class along with all of the data that we want inside of it. This is all we have to do.

One of the reasons I wanted to include this, there is a lot of confusion and misinformed notion that ruby gems are these crazy magical kinds of code libraries. Gems are just Ruby code in helper modules.

Next, we need create a repo for this

  • git status
  • git add .
  • git commit -m "Dev tool initial commit"

now we need to set up the repo.

Let's go to GitHub, create a new repository. Paste in Devcamp_View_Tool and click create repository. Let's copy the link, now coming back to the terminal, paste the link in (should say git push -u origin master)

Once that is all live, you can see that this has all of our code. One really neat thing is that we have this cool readme file that was generated.

We have one other thing that we have to do. Let's take a look at the readme file, I'm going to copy the set of instructions that we put inside the gemspec. Delete lines 3-5, and paste the instructions in using a blockquote (>).

There's one other thing that we need to do, come back to the terminal. I want to add an item to our .gitignore file, type in echo "*.gem" >> .gitignore and hit return.

Now if you open up your codebase and click gitignore, you can see that this was added to the file. Say that you push this up to github and you didn't have that in your gitignore file, you'd actually have an error. Once we generate the gem, It's going to create the actual gemfile. If another developer tries to call it, they're going to get an error. You should not have the actual gem itself on GitHub because rails and ruby need to process it. They run their own type of compilation and we don't want to get in the way of that.

I'm going to

  • git status
  • git add .
  • git commit -m "Updated gitignore file and readme"
  • git push

Switching over to Chrome and hitting refresh. You can see that this looks better.

We are ready to actually create our gem.

Come to the terminal and type gem build devcamp_view_tool.gemspec and hit return. If everything works it's going to generate the gem.

  • git status
  • git add .
  • git commit -m "Generate app and updated readme"
  • git push

Technically, I didn't have to say generate app right there because there is no app that got pushed up. I like to do that because if I ever have a bug I know that I can go back to this point in time to see at which commit did I generate the app.

I should be able to simply go into the gemfile, scroll all the way down to the bottom, type gem 'devcamp_view_tool', git: 'https://github.com/jordanhudgens/devcamp_view_tool'

Make sure you're in the DevcampPortfolio and we can run bundle install if everything works it should go out and grab the new gem that we just created and it should pull down that dependency.

If there is an error it will show it right here.

Type rails s, and let's see if we see our copyright works. Coming to the application, hit refresh, if everything works this should be identical, it looks like it is working. We are now pulling from our own codebase. We are now pulling from our ruby gem code.

Let's refactor the application_controller.rb to this

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  include DeviseWhitelist
  include SetSource
  include CurrentUserConcern
  include DefaultPageContent
end

Now go into application_helper.rb and add

def copyright_generator
  DevcampViewTool::Renderer.copyright 'Jordan Hudgens', 'All rights reserved'
end

Now we can come to application.html.erb and change <%= @copyright %> to <%= copyright_generator %>

Come to Chrome, everything is working perfectly. This is a view helper so it makes sense that it would be here. We could have put it in application controller but I like to put things in the controller that are specific to data. However, something as basic as the copyright, I don't think that that needs to be in the controller.

  • git status
  • git add .
  • git commit -m "Integrated new gem into rails app for copyright"
  • git push origin rubygem

In the next guide, we are going to walk through how we can publish our gem on rubygem so they're available to the world.

Resources