Monthly Archives: November 2015

creating a ruby gem

So i had a Votable module in my rails app that a few of my model classes were using.  Say I had other rails projects that could use this module, and you want to make it so that if you edit this module you wouldn’t have to go to other applications and change the code there as well.  So you could also create a gem for this module, install it like you would any other gem and delete the module I was using in my application.  So here is how that works.

First lets register at rubygems.org, it’s free to signup and simple.  Once you signup you need to have a gem called gem cutter installed in your computer.  So ‘gem install gem cutter’ and bundle install.

Then go to a new folder and create a new folder like so, mkdir votable.  Inside that folder create a gem spec file called whateveryouwant.gemspec i’ll name it votable.gemspec.  Then we give it some specifications like shown below.

Gem::Specification.new do |s|
s.name = ‘votable’
s.version = ‘0.0.0’
s.date = ‘2015-11-02’
s.summary = ‘Votable module for voting feature in postit app’
s.description = ‘A voting module gem’
s.authors = [‘Brian Jin’]
s.email = ‘example@gmail.com’
s.files = [“lib/votable.rb”]
s.homepage = ‘http://github.com’
s.license = ‘MIT’
end

  • Don’t worry about the homepage right now.  Normally you want your code inside a github repo and you can fill out the url for that page.
  • the s.files is important, give it the directory of the ruby file we are about to create, which should be inside a lib folder.

Create a lib folder, mkdir lib.  Inside of this lib folder create a ruby file votable.rb.  Our code will be entered here.

In the votable.rb file I will just copy and paste my module that I had in my application shown below.

module Votable
extend ActiveSupport::Concern

included do
has_many :votes, as: :votable
end

def total_votes
self.up_votes – self.down_votes
end

def up_votes
self.votes.where(:vote => true).size
end

def down_votes
self.votes.where(:vote => false).size
end

end

Switch over to the terminal.  Because we have the gem cutter gem installed we can use this command to create out gem.

gem build votable.gemspec

This will produce a .gem file.

Now I can push this to rubygems.org and make it available for download.  It will also ask for your user credentials you created earlier.

gem push votable-0.0.0.gem

Now type

gem list -r votable

You can see that it lists your gem already.  Go to rubygems.org and you can already see your gem.

Now I go back to my application and delete the module I just created a gem for.  Then I can add the gem in my gem file and bundle install.  Restart the server and you should see a working application with the same features as before.

If I were to debug errors and make changes on the gem I created, I can edit the ruby gem and save, then edit the version number on the gemspec file to 0.0.1 for example.  Then issue the command gem build votable.gemspec again and it will create a new version of the edited gem as 0.0.1.  Then I will push this using this command

gem push votable-0.0.1.gem

Now I just change the gem in my application to say version 0.0.1 and bundle install.

But this not a great work flow, every time you have a bug and make a change you have to go and update the version of your gem and deploy it.  That makes testing and fixing bugs very painful.  So instead you can work on it locally and tell your rails app that this is local.  We do this by specifying with a path parameter after the gem and give it the address where the gem lives.

gem ‘votable’, ‘= 0.0.1’, path: ‘/Users/somepath/to/your/gemfile/votable’

Then bundle install.  Now we can work locally on any changes for this gem.

There is more detail on option on the rails guides site http://guides.rubygems.org/make-your-own-gem/

Enjoy!